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

时间:2011-02-19 11:43:55

标签: c# silverlight

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

我一直在尝试使用Dependency Properties和INotifyPropertyChanged来完成此操作,但现在又决定以干净的方式重新开始。

// Current Sttings类:

public static class CurrentSettings
{
    public static Color Color { get; set; }
}

// MainPage 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>

// ColorPicker用户控件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>

// ColorPicker用户控制代码背后:

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;
    }
}

//笔选择器用户控件XAML:

<ListBox x:Name="LayoutRoot"/>

//笔选择器用户控件XAML代码背后:

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) });
    }
}

2 个答案:

答案 0 :(得分:3)

您与INotifyPropertyChanged走在了正确的轨道上。从设置类开始,但将Color设置为实现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>

现在为您的颜色选择器添加CurrentSettings私有属性: -

private CurrentSettings CurrentSettings
{
   get
   {
        return (CurrentSettings)Application.Current.Resources["CurrentSettings"];
   }
}

最后在矩形Fill属性上使用绑定,如下所示: -

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

答案 1 :(得分:1)

这里有很多移动部件 - 一个colorPicker用户控件,它可以更改主窗体上的POCO,从而更新另一个用户控件中添加的项目PenSelector - 如果我理解正确的话。如果您将DP添加到您的用户控件并将INotifyPropertyChanged添加到您的POCO然后将DP绑定到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;
    }

用户控件 - ColorPicker

<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>

其代码:

public static readonly DependencyProperty CurrentColorProperty=
        DependencyProperty.Register("CurrentColor",
            typeof(SolidColorBrush), typeof(ColorPicker),
            new PropertyMetadata(new SolidColorBrush(Colors.Gray)));

    public SolidColorBrush CurrentColor
    {
        get
        {
            return (SolidColorBrush)GetValue(CurrentColorProperty);
        }
        private set
        {
            SetValue(CurrentColorProperty, value);
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Button b = (Button)sender;
        Shape r = (b.Content) as Shape;
        SolidColorBrush sb = new SolidColorBrush(Colors.Yellow);
        sb = (SolidColorBrush)r.Fill;
        this.CurrentColor = sb;
    }

用户控制PenSelector

xaml就像你只有一个ListBox一样,所有工作都在

背后的代码中
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和DP分别定义为SolidColorBrushes,尽管您可能希望使用Color和转换器转换为Brush。 CurrentSelected类实例设置被分配给mainWindows datacontext。 在ColorPicker上,我刚刚将代码放在一个Button Click处理程序中,并根据xaml中指定的Fill颜色获取颜色。这将更新选取器上的CurrentColor DP。 PenSelector设置矩形,并绑定到自己的DP,然后剩下的就是在CurrentSelected公开的Color属性的MainWindow中设置数据绑定。 DP定义默认值。还有其他方法可以做到这一切,但这取决于您的要求(一如既往)!