C# Silverlight:如何根据当前设置类动态更新属性?
下面是该示例的完整代码。我有一个名为ColorPicker的用户控件,它包含3个按钮,每个按钮显示一种颜色。单击按钮时,将设置CurrentSettings类中的颜色属性。我要做的是更改主页上矩形的颜色以匹配新的CurrentSettings.color和第二个用户控件中列表框中矩形的颜色(添加在代码隐藏中),以便也更改颜色以匹配新的CurrentSettings.color 我一直在尝试使用依赖属性和INotifyPropertyChanged来完成这项工作,但没有成功,现在我决定从头开始 //当前标准等级:C# Silverlight:如何根据当前设置类动态更新属性?,c#,silverlight,C#,Silverlight,下面是该示例的完整代码。我有一个名为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将所有部分放在一个地方,因为我觉得这样可以更好地分离关注点和关注点可重用性。