【问题标题】:Silverlight 4 - Binding does not work on enum types of POCO objects?Silverlight 4 - 绑定不适用于枚举类型的 POCO 对象?
【发布时间】:2011-10-18 15:17:40
【问题描述】:

我有一个 WCF RIA POCO 对象 -> 具有描述其状态的枚举类型的交通灯。

[DataContract]
public class TrafficLight
{
    [Key]
    [DataMember]
    public long Id { get; set; }    

    [DataMember]
    public Longitude Longitude { get; set; }

    [DataMember]
    public Latitude Latitude { get; set; }

    [DataMember]
    public TrafficLightState SelectedLight { get; set; }
}

[DataMember]
public enum TrafficLightState
{
    [EnumMember]
    Red = 0,

    [EnumMember]
    Yellow = 1,

    [EnumMember]
    Green = 2
}

因此,给定 WCF RIA 服务,我需要将此交通信号灯对象传递给 Silverlight 客户端应用程序:

public IEnumerable<TrafficLight> GetTrafficLightsForCity(int cityId)
{
    return Data.GetTrafficLightsForCity(cityId).AsEnumerable();
}

所以效果很好。我得到了我的列表,一切都很好,直到我决定将列表绑定到一个显示我的交通信号灯的网格......(PS。这是一个有点像模拟城市的游戏):

交通灯在网格中的显示方式是通过一个小控件来显示灯的状态 -> 红色、黄色、绿色以及其他一些内容。现在,我将只向您展示 Light 状态和 ID:

<UserControl x:Name="MiniTrafficLightControl" x:Class="UI.MiniTrafficLight"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="15" 
    d:DesignWidth="15"
    Width="15" Height="15">
    <StackPanel Orientation="Horizontal">
        <Border x:Name="BrdGreen" Visibility="Visible" CornerRadius="10" Width="15" Height="15" Margin="0" ToolTipService.ToolTip="Runing" d:IsLocked="True">
        <Border.Background>
            <RadialGradientBrush  GradientOrigin="0.4,0.3" Center="0.4,0.3" RadiusX="0.5" RadiusY="0.5">
            <RadialGradientBrush.GradientStops>
                <GradientStop Color="LightGreen" Offset="0" />
            <GradientStop Color="Green" Offset="0.95" />
            </RadialGradientBrush.GradientStops>
        </RadialGradientBrush>
        </Border.Background>
    </Border>
    <Border x:Name="BrdYellow" Visibility="Collapsed" CornerRadius="10" Width="15" Height="15" Margin="0" ToolTipService.ToolTip="Action Pending" d:IsHidden="True" d:IsLocked="True">
        <Border.Background>
            <RadialGradientBrush  GradientOrigin="0.4,0.3" Center="0.4,0.3" RadiusX="0.5" RadiusY="0.5">
            <RadialGradientBrush.GradientStops>
                <GradientStop Color="Yellow" Offset="0" />
            <GradientStop Color="Orange" Offset="0.95" />
            </RadialGradientBrush.GradientStops>
        </RadialGradientBrush>
        </Border.Background>
    </Border>
    <Border x:Name="BrdRed" Visibility="Collapsed" CornerRadius="10" Width="15" Height="15" Margin="0" ToolTipService.ToolTip="Stopped" d:IsHidden="True" d:IsLocked="True">
        <Border.Background>
            <RadialGradientBrush  GradientOrigin="0.4,0.3" Center="0.4,0.3" RadiusX="0.5" RadiusY="0.5">
            <RadialGradientBrush.GradientStops>
                <GradientStop Color="Orange" Offset="0" />
            <GradientStop Color="Red" Offset="0.95" />
            </RadialGradientBrush.GradientStops>
        </RadialGradientBrush>
        </Border.Background>
    </Border>
    </StackPanel>
</UserControl>

以及控件背后的代码:

namespace UI
{
    public partial class MiniTrafficLight : UserControl
    {
        public static readonly DependencyProperty TrafficLightStateProperty = DependencyProperty.Register("TrafficLightState", typeof(TrafficLightState), typeof(MiniTrafficLight), null);

        public TrafficLightState TrafficLightState
    {
        get
        {
            return (TrafficLightState)this.GetValue(TrafficLightStateProperty);
        }
        set
        {
            if (value == TrafficLightState.Red)
        {
            this.BrdRed.Visibility = System.Windows.Visibility.Visible;
            this.BrdGreen.Visibility = System.Windows.Visibility.Collapsed;
            this.BrdYellow.Visibility = System.Windows.Visibility.Collapsed;
        }
        else if (value == TrafficLightState.Yellow)
        {
            this.BrdRed.Visibility = System.Windows.Visibility.Collapsed;
            this.BrdGreen.Visibility = System.Windows.Visibility.Collapsed;
            this.BrdYellow.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
             this.BrdRed.Visibility = System.Windows.Visibility.Collapsed;
                     this.BrdGreen.Visibility = System.Windows.Visibility.Visible;
             this.BrdYellow.Visibility = System.Windows.Visibility.Collapsed;
        }

                this.SetValue(TrafficLightStateProperty, value);
        }
        }
    }
}

所以现在的问题是,如果页面上的任何地方都有一个网格,该网格使用网格内的 MiniTraficLight 控件显示所有交通灯对象 - MiniTrafficLight 控件永远不会工作......或者它永远不会显示绿色红色或黄色灯.我已经调试了服务并验证了在从数据库中读取每个交通灯对象时设置了 TrafficLightState 属性。我还可以在客户端 silverlight 应用程序上验证每个 TrafficLight 对象的 TrafficLightState 是否正确到达(又名...已设置)。

但是,如果我在不绑定的情况下手动设置 MiniTrafficLight 的控件 TrafficLightState,它就可以工作。如果我使用绑定,它永远不会出现。无论有没有转换器,MiniTrafficLight 控件上的属性都不会被调用。我知道的原因是我在属性的 set 访问器上添加了一个 MessageBox.Show(...) 并且我没有看到任何消息框。如果我设置断点 - 他们永远不会到达。下面是在网格内显示交通灯对象的示例代码:

<datagrid:DataGrid x:Name="ReceiverNodesDataGrid" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True" HorizontalAlignment="Stretch" SelectionMode="Single">
    <datagrid:DataGrid.Columns>
        <datagrid:DataGridTemplateColumn Header="Status">
            <datagrid:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <local:MiniTraficLight TrafficLightState="{Binding TrafficLightState}"/>
        </DataTemplate>
            </datagrid:DataGridTemplateColumn.CellTemplate>
    </datagrid:DataGridTemplateColumn>
        <datagrid:DataGridTextColumn Header="Id" Binding="{Binding Id}" />
    </datagrid:DataGrid.Columns>
</datagrid:DataGrid>

知道为什么这个绑定不起作用吗?

谢谢大家, 马丁

【问题讨论】:

    标签: c# silverlight xaml data-binding silverlight-4.0


    【解决方案1】:

    显然,解决这个问题的诀窍是正确实现依赖属性。啊啊啊!

    namespace UI
    {
        public partial class MiniTrafficLight : UserControl
        {
            private static PropertyMetaData trafficLightStateMetaData = new PropertyMetaData(new PropertyChangedCallBack(TrafficLightState_Changed));
            public static readonly DependencyProperty TrafficLightStateProperty = DependencyProperty.Register("TrafficLightState", typeof(TrafficLightState), typeof(MiniTrafficLight), trafficLightStateMetaData);
    
            public TrafficLightState TrafficLightState
            {
                get { return (TrafficLightState)this.GetValue(TrafficLightStateProperty); }
                set { this.SetValue(TrafficLightStateProperty, value); }
            }
    
            private static void TrafficLightState_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                MiniTrafficLight sender = d as MiniTrafficLight;
                TrafficLightState state = (TrafficLightState)e.NewState;
    
                if( state == TrafficLightState.Red )
                {
                    //...
                }
                else if ( state == TrafficLightState.Yellow )
                {
                    //...
                }
                else
                {
                    //...
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-07
      • 2016-03-13
      • 1970-01-01
      • 2018-06-19
      • 2013-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      相关资源
      最近更新 更多