因此我在xaml中设置了一个ItemsControl,例如:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<local:ToggleButton Command="{Binding DataContext.ItemSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type WrapPanel}}}"
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}"
Text="{Binding DataContext.ItemEnum, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Converter={StaticResource EnumToStringConverter}}"
IsActive="{Binding DataContext.Selected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, UpdateSourceTrigger=PropertyChanged}"
Width="96"
Height="88"
Margin="5" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我有4个依赖项属性Command
,CommandParameter
,Text
和IsActive
。
前三个依赖项属性正常工作,设置了文本,命令回调与参数一起工作。
IsActive
属性不起作用。
主视图模型中的Items属性定义为:
List<ItemViewModel> Items { get; set; }
ItemViewModel定义为:
public class ItemViewModel : INotifyPropertyChanged
{
public ItemViewModel()
{
this.Selected = true;
}
private bool? _selected;
public event PropertyChangedEventHandler PropertyChanged;
public ItemEnum ItemEnum { get; set; }
public bool? Selected
{
get { return this._selected; }
set
{
this._selected = value;
this.OnPropertyChanged(nameof(this.Selected));
}
}
protected virtual void OnPropertyChanged(string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ToggleButton.xaml.cs文件中IsActive
属性的依赖项属性如下:
public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(nameof(IsActive), typeof(bool?), typeof(ToggleButton), new PropertyMetadata(null, IsActiveSetCallback));
private static void IsActiveSetCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var button = (ToggleButton)obj;
button.IsActive = (bool)(e.NewValue ?? e.OldValue);0xa5, 0xa5));
}
我在主视图模型中的命令回调如下:
this.ItemSelectedCommand =
new DelegateCommand(
itemVm =>
{
bool? setTo = !((ItemViewModel) itemVm).Selected;
this.Items.ForEach(i => i.Selected = false);
((ItemViewModel) itemVm).Selected = setTo;
});
同样,其他依赖项属性(定义与IsActiveProperty
基本相同)也正常工作,因此,当我单击该项目时,上述命令被调用(由断点验证),该项目的Selected标志被正确切换,但是IsActiveSetCallback永远不会被击中。我看不到我在做什么错,但是很明显这是什么。
有人看到我没看到的东西吗?
谢谢!
答案 0 :(得分:-1)
花了太多时间尝试解决这个问题后,我当然会在发布此问题后半小时内自己解决问题。
我从Microsoft DependencyProperty文档(特别是有关“依赖项属性设置优先级列表”的部分)中提取了此信息:
本地值。可以通过“包装器”属性的便利性来设置局部值,该属性还等同于在XAML中设置为属性或属性元素,或者通过使用特定实例的属性来调用SetValue API。如果您通过使用绑定或资源来设置本地值,则这些值将像设置直接值一样优先工作。
因此,我在ToggleButton.xaml.cs中的两个位置设置了this.Active
,一次是在构造函数中将其设置为默认值,一次是在IsActiveSetCallback ..这样做的结果是,我覆盖了绑定,无论如何都不需要这些调用。很简单!