我正在玩一个LED控件来学习更多关于用户控件中数据绑定的知识,并且被迫使用依赖属性,因为VS2008告诉我必须这样做。我的应用程序很简单——我有一个窗口,其中显示几个LED控件,每个控件上面都有一个数字,也可以选择在其旁边显示一个。LED应该可以用默认颜色定义,也可以改变状态。
我开始写一个LED控制,这似乎非常好。首先,我从这样的代码开始:
<UserControl x:Class="LEDControl.LED"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="Auto" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- LED portion -->
<Ellipse Grid.Column="0" Margin="3" Height="{Binding LEDSize}" Width="{Binding LEDSize}" Fill="{Binding LEDColor}" StrokeThickness="2" Stroke="DarkGray" />
<Ellipse Grid.Column="0" Margin="3" Height="{Binding LEDSize}" Width="{Binding LEDSize}">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.5,1.0">
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1.5" ScaleY="1.5"/>
<TranslateTransform X="0.02" Y="0.3"/>
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Offset="1" Color="#00000000"/>
<GradientStop Offset="0.4" Color="#FFFFFFFF"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<!-- label -->
<TextBlock Grid.Column="1" Margin="3" VerticalAlignment="Center" Text="{Binding LEDLabel}" />
</Grid>
</UserControl>
this.DataContext = this
就像我一直做的那样:
/// <summary>
/// Interaction logic for LED.xaml
/// </summary>
public partial class LED : UserControl, INotifyPropertyChanged
{
private Brush state_color_;
public Brush LEDColor
{
get { return state_color_; }
set {
state_color_ = value;
OnPropertyChanged( "LEDColor");
}
}
private int led_size_;
public int LEDSize
{
get { return led_size_; }
set {
led_size_ = value;
OnPropertyChanged( "LEDSize");
}
}
private string led_label_;
public string LEDLabel
{
get { return led_label_; }
set {
led_label_ = value;
OnPropertyChanged( "LEDLabel");
}
}
public LED()
{
InitializeComponent();
this.DataContext = this;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged( string property_name)
{
if( PropertyChanged != null)
PropertyChanged( this, new PropertyChangedEventArgs( property_name));
}
#endregion
}
在这一点上,我可以更改属性值,并看到LED改变大小、颜色和标签。太好了!
我希望LED控件可以在我编写的其他小部件中重用,下一步是创建另一个UserControl(在单独的程序集中),名为
IOView
.
IOView公司
在这一点上是非常基本的:
IOView.xaml文件
<UserControl x:Class="IOWidget.IOView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:led="clr-namespace:LEDControl;assembly=LEDControl"
Height="Auto" Width="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" HorizontalAlignment="Center" Text="{Binding Path=Index}" />
<led:LED Grid.Row="1" HorizontalContentAlignment="Center" HorizontalAlignment="Center" LEDSize="30" LEDColor="Green" LEDLabel="Test" />
</Grid>
</UserControl>
请注意,我可以在设计时修改XAML中的LED属性,一切都按预期工作:
“不能对类型为'LED'的'LEDColor'属性设置'Binding'。”。只能在DependencyObject的DependencyProperty上设置'Binding'
哎呀!我甚至没有意识到这一点,因为我还没有自己的图形用户界面控件之前。自从
LEDColor
已数据绑定到椭圆,我添加了一个名为Color的DependencyProperty。
发光二极管.xaml.cs
public static DependencyProperty ColorProperty = DependencyProperty.Register( "Color", typeof(Brush), typeof(LED));
public Brush Color
{
get { return (Brush)GetValue(ColorProperty); }
set {
SetValue( ColorProperty, value);
LEDColor = value;
}
}
注意,我设置了属性
发光二极管
在setter中,因为椭圆就是这样知道它应该是什么颜色的。
下一步是通过绑定到设置IOView中LED的颜色IOView.InputColor:
IOView.xaml.cs:
/// <summary>
/// Interaction logic for IOView.xaml
/// </summary>
public partial class IOView : UserControl, INotifyPropertyChanged
{
private Int32 index_;
public Int32 Index
{
get { return index_; }
set {
index_ = value;
OnPropertyChanged( "Index");
}
}
private Brush color_;
public Brush InputColor
{
get { return color_; }
set {
color_ = value;
OnPropertyChanged( "InputColor");
}
}
private Boolean state_;
public Boolean State
{
get { return state_; }
set {
state_ = value;
OnPropertyChanged( "State");
}
}
public IOView()
{
InitializeComponent();
this.DataContext = this;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged( string property_name)
{
if( PropertyChanged != null)
PropertyChanged( this, new PropertyChangedEventArgs( property_name));
}
#endregion
}
而且在IOView.xaml文件,我将LED改为:
<led:LED Grid.Row="1" HorizontalContentAlignment="Center" HorizontalAlignment="Center" LEDSize="30" Color="{Binding InputColor}" />
BindingExpression路径错误:在“object'''LED'(Name='')上找不到“InputColor”属性。装订xpression:Path=InputColor;DataItem='LED'(Name='');目标元素为'LED'(Name='');目标属性为'Color'(键入'Brush')
隐马尔可夫模型。。。所以出于某种原因,我的数据绑定搞砸了。我可以通过数据绑定让LED自己工作,但是一旦我将它包装到另一个控件中并设置它的datacontext,它就不工作了。我不知道在这一点上该尝试什么。