C# Silverlight:如何根据当前设置类动态更新属性?

C# Silverlight:如何根据当前设置类动态更新属性?,c#,silverlight,C#,Silverlight,下面是该示例的完整代码。我有一个名为ColorPicker的用户控件,它包含3个按钮,每个按钮显示一种颜色。单击按钮时,将设置CurrentSettings类中的颜色属性。我要做的是更改主页上矩形的颜色以匹配新的CurrentSettings.color和第二个用户控件中列表框中矩形的颜色(添加在代码隐藏中),以便也更改颜色以匹配新的CurrentSettings.color 我一直在尝试使用依赖属性和INotifyPropertyChanged来完成这项工作,但没有成功,现在我决定从头开始 /

下面是该示例的完整代码。我有一个名为ColorPicker的用户控件,它包含3个按钮,每个按钮显示一种颜色。单击按钮时,将设置CurrentSettings类中的颜色属性。我要做的是更改主页上矩形的颜色以匹配新的CurrentSettings.color和第二个用户控件中列表框中矩形的颜色(添加在代码隐藏中),以便也更改颜色以匹配新的CurrentSettings.color

我一直在尝试使用依赖属性和INotifyPropertyChanged来完成这项工作,但没有成功,现在我决定从头开始

//当前标准等级:

public static class CurrentSettings
{
    public static Color Color { get; set; }
}
//主页XAML

<Grid x:Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="33*"/>
        <ColumnDefinition Width="33*"/>
        <ColumnDefinition Width="33*"/>
    </Grid.ColumnDefinitions>
    <local:ColorPicker/>
    <Rectangle Grid.Column="1" Name="rec" Width="160" Height="80" Fill="Yellow"/>
    <local:PenSelector Grid.Column="2"/>
</Grid>
//笔选择器用户控件XAML:

<StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
    <Button x:Name="Red" Width="40" Height="40" Click="Red_Click">
        <Button.Content>
            <Rectangle Width="30" Height="30" Fill="Red"/>
        </Button.Content>
    </Button>
    <Button x:Name="Green" Width="40" Height="40" Click="Green_Click">
        <Button.Content>
            <Rectangle Width="30" Height="30" Fill="Green"/>
        </Button.Content>
    </Button>
    <Button x:Name="Blue" Width="40" Height="40" Click="Blue_Click">
        <Button.Content>
            <Rectangle Width="30" Height="30" Fill="Blue"/>
        </Button.Content>
    </Button>
</StackPanel>

//笔选择器用户控件XAML代码隐藏:

public partial class ColorPicker : UserControl
{
    public ColorPicker()
    {
        InitializeComponent();
    }

    private void Red_Click(object sender, RoutedEventArgs e)
    {
        CurrentSettings.Color = Colors.Red;
    }

    private void Green_Click(object sender, RoutedEventArgs e)
    {
        CurrentSettings.Color = Colors.Green;
    }

    private void Blue_Click(object sender, RoutedEventArgs e)
    {
        CurrentSettings.Color = Colors.Blue;
    }
}
public partial class PenSelector : UserControl
{
    public PenSelector()
    {
        InitializeComponent();

        LayoutRoot.Items.Add(new Rectangle() { Width = 160, Height = 80, Fill = new SolidColorBrush(Colors.Yellow) });
        LayoutRoot.Items.Add(new Rectangle() { Width = 160, Height = 80, Fill = new SolidColorBrush(Colors.Yellow) });
    }
}

您使用了
INotifyPropertyChanged
,这是正确的。从settings类开始,但将颜色设置作为实现
INotifyPropertyChanged
的类的实例属性

 public class CurrentSettings : INotifyPropertyChanged
 {
     private Color _Color;
     public Color Color
     {
        get { return _Color; }
        set { _Color = value; NotifyPropertyChanged("Color"); }
     }
     private void NotifyPropertyChanged(string name)
     {
         if (PropertyChanged != null)
             PropertyChanged(this, new PropertyChangedEventArgs(name);
     }
     public event PropertyChangedEventHandler PropertyChanged;
 }
现在将此实例放在您的
App.Xaml
资源中:-

 <Application.Resources>
     <local:CurrentSettings x:Key="CurrentSettings" />
 </Application.Resources>
最后对矩形
Fill
属性使用如下绑定:-

<Rectangle Grid.Column="1" Name="rec">
    <Rectangle.Fill>
         <SolidColorBrush Color="{Binding Color, Source={StaticResource CurrentSettings}}"/>
    </Rectangle.Fill>
</Rectangle>

这里有很多移动部件-一个colorPicker用户控件,用于更改主窗体上的POCO,进而更新另一个用户控件中添加的项目-一个PenSelector-如果我理解正确的话。如果将DPs添加到usercontrols,并将INotifyPropertyChanged添加到POCO,则反过来将DPs绑定到POCO公共属性,您应该能够通过部分之间的某种解耦实现所需的交互:

Poco:

public class CurrentSelected:INotifyPropertyChanged
{

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void Notify(string propName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
    #endregion


    private SolidColorBrush color;

    public SolidColorBrush Color
    {
        get { return color; }
        set { 
            if (this.color==value) return;
            this.color = value;
            Notify("Color");
        }
    }

    public CurrentSelected() { 
        this.color = new  SolidColorBrush(Colors.Orange);
    }

}
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="33*"/>
        <ColumnDefinition Width="33*"/>
        <ColumnDefinition Width="33*"/>
    </Grid.ColumnDefinitions>
    <local:ColorPicker CurrentColor="{Binding Path=Color, Mode=TwoWay}" Grid.Column="0"/>
    <Rectangle Fill="{Binding Path=Color}" Grid.Column="1" Width="160" Height="80" />
    <local:PenSelector ColorSelected="{Binding Path=Color, Mode=TwoWay}" Grid.Column="2"/>
</Grid>
CurrentSelected Settings = new CurrentSelected();

    public MainPage()
    {
        InitializeComponent();
        this.DataContext = this.Settings;
    }
主窗口:

public class CurrentSelected:INotifyPropertyChanged
{

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void Notify(string propName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
    #endregion


    private SolidColorBrush color;

    public SolidColorBrush Color
    {
        get { return color; }
        set { 
            if (this.color==value) return;
            this.color = value;
            Notify("Color");
        }
    }

    public CurrentSelected() { 
        this.color = new  SolidColorBrush(Colors.Orange);
    }

}
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="33*"/>
        <ColumnDefinition Width="33*"/>
        <ColumnDefinition Width="33*"/>
    </Grid.ColumnDefinitions>
    <local:ColorPicker CurrentColor="{Binding Path=Color, Mode=TwoWay}" Grid.Column="0"/>
    <Rectangle Fill="{Binding Path=Color}" Grid.Column="1" Width="160" Height="80" />
    <local:PenSelector ColorSelected="{Binding Path=Color, Mode=TwoWay}" Grid.Column="2"/>
</Grid>
CurrentSelected Settings = new CurrentSelected();

    public MainPage()
    {
        InitializeComponent();
        this.DataContext = this.Settings;
    }
用户控件-颜色选择器

<StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
    <Button Click="Button_Click">
        <Button.Content>
            <Rectangle Fill="Red"/>
        </Button.Content>
    </Button>

    <Button Click="Button_Click">
        <Button.Content>
            <Rectangle Fill="Green"/>
        </Button.Content>
    </Button>
    <Button Click="Button_Click">
        <Button.Content>
            <Rectangle Fill="Blue" />
        </Button.Content>
    </Button>
</StackPanel>
用户控制笔选择器

<StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
    <Button Click="Button_Click">
        <Button.Content>
            <Rectangle Fill="Red"/>
        </Button.Content>
    </Button>

    <Button Click="Button_Click">
        <Button.Content>
            <Rectangle Fill="Green"/>
        </Button.Content>
    </Button>
    <Button Click="Button_Click">
        <Button.Content>
            <Rectangle Fill="Blue" />
        </Button.Content>
    </Button>
</StackPanel>
xaml就像您的列表框一样,所有的工作都在代码背后

public static readonly DependencyProperty ColorSelectedProperty =
        DependencyProperty.Register(
            "ColorSelected", 
            typeof(SolidColorBrush),
            typeof(PenSelector), 
            new PropertyMetadata(new SolidColorBrush(Colors.Yellow)));

    public SolidColorBrush ColorSelected
    {
        get
        {
            return (SolidColorBrush)GetValue(ColorSelectedProperty);
        }
        set
        {
            SetValue(ColorSelectedProperty, value);
        }
    }

    public PenSelector()
    {
        InitializeComponent();

        LayoutRoot.Items.Add(addRectangle());
        LayoutRoot.Items.Add(addRectangle());
    }

    private Rectangle addRectangle()
    {
        Rectangle r = new Rectangle() { Width = 160, Height = 80 };
        Binding b = new Binding();
        b.Source=this;
        b.Path=new PropertyPath("ColorSelected");
        b.Mode=BindingMode.OneWay;
        r.SetBinding(Rectangle.FillProperty, b);
        return r;
    }
我已经将POCO和DPs分别定义为SolidColorBrush,尽管您可能希望使用颜色和转换器来转换为笔刷。CurrentSelected类实例设置已分配给mainWindows datacontext。
在ColorPicker上,我刚刚将代码放在一个按钮点击处理程序中,它根据xaml中指定的填充颜色获取颜色。这将更新选择器上的CurrentColor DP。PenSelector设置带有绑定到自己DP的矩形,然后剩下的就是在主窗口中设置CurrentSelected公开的Color属性的数据绑定。DPs定义默认值。有其他方法可以做到这一切,但这取决于您的要求(一如既往)

这很有效。对于任何阅读我的示例的人来说,我犯了一个错误-矩形的Fill属性应该是一个设置了颜色的SolidColorBrush。@descf:这是一个很好的观点,我没有注意到它。我已经做了相应的编辑。这一次也是第一次。杰出的在我的上下文中权衡每个解决方案的优点需要一段时间。@descf-我想其中一些是个人的选择,但我喜欢让我的usercontrols不知道任何POCO+INPC对象,并通过bindings/datacontext将所有部分放在一个地方,因为我觉得这样可以更好地分离关注点和关注点可重用性。