我想根据布尔值更改矩形的填充。我有以下课程。
扩展INotifyPropertyChanged的基类:
public class PropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
模型:
public class ChangingVariable : PropertyChangedBase
{
public ChangingVariable()
{
Variable = true;
}
private bool _variable;
public bool Variable
{
get
{
return _variable;
}
set
{
if (_variable.CompareTo(value) != 0)
{
_variable = value;
OnPropertyChanged();
}
}
}
}
ViewModel:
public class BooleanRectangleViewModel : PropertyChangedBase
{
public ChangingVariable Model { get; set; }
}
这是我的看法,它不能正常工作(填充是灰色的):
xaml:
<UserControl.DataContext>
<viewModels:BooleanRectangleViewModel x:Name="ViewModel"/>
</UserControl.DataContext>
<Rectangle x:Name="Rectangle">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Gray" />
<Style.Triggers>
<DataTrigger Binding="{Binding Model.Variable}" Value="true">
<Setter Property="Fill" Value="GreenYellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
CS:
public partial class BooleanRectangleView
{
public BooleanRectangleView()
{
InitializeComponent();
ViewModel.Model = new ChangingVariable();
}
}
但是,当我更改它以使数据上下文是Model而不是ViewModel时,它可以工作(填充为绿色):
xaml:
<UserControl.DataContext>
<models:ChangingVariable x:Name="ViewModel" />
</UserControl.DataContext>
<Rectangle x:Name="Rectangle">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Gray" />
<Style.Triggers>
<DataTrigger Binding="{Binding Variable}" Value="true">
<Setter Property="Fill" Value="GreenYellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
CS:
public partial class BooleanRectangleView
{
public BooleanRectangleView()
{
InitializeComponent();
ViewModel = new ChangingVariable();
}
}
为什么在它们之间的ViewModel不起作用?
据我所知,当您在模板或样式中进行绑定时,最好使用RelativeSource
。我不太确定,但是您可以尝试:
<Rectangle x:Name="Rectangle">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Gray" />
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.Model.Variable, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="true">
<Setter Property="Fill" Value="GreenYellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
我对WPF / MVVM也很陌生,但是我想分享我在短短的两到三个月中学到的知识,这可能会帮助其他人解决绑定问题。
每当绑定不起作用时,最可能的原因是绑定引擎无法找到绑定源或源属性。实现INotifyPropertyChanged
(或使用DependencyProperty
)只是为绑定提供了一种在源属性的值更改时得到通知的方式。如果您删除该部分,则绑定将像在OneTime
模式下一样起作用。原因很简单-绑定引擎足够智能,可以知道它必须从source属性中获取值才能使目标属性起作用。
例如,您有<Border BorderBrush="{Binding MyBorderColor}" ....>
。当控件将要呈现自身时,该控件需要知道边框是什么颜色,否则它将无法继续呈现。绑定引擎被迫搜索source属性MyBorderColor
。如果绑定失败,则BorderBrush
目标属性将不会获得值,这将导致Border使用任何默认值或继承的值。如果MyBorderColor
未实现'INotifyPropertyChanged'也不是a DependencyProperty
,则如果MyBorderColor
在运行时某个时间更改值,则该值将不会反映在中BorderBrush
,因为绑定引擎不知道source属性已更改。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句