如果我理解你的問題正確的您正在尋找一種方式,從孩子到其父複選框布布爾河了複選框值。
我已經爲樹視圖做了類似的解決方案。此代碼可行,但如果集合發生更改,則需要進行一些事件分離。
以下是用於運行此解決方案的ViewModel部分的一組類。
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class StructureViewModel : ViewModelBase
{
private bool? _isChecked = false;
public bool? IsChecked
{
get { return _isChecked; }
set
{
if (_isChecked != value)
{
_isChecked = value;
RaisePropertyChanged("IsChecked");
}
}
}
public string Name { get; set; }
}
public class ChildViewModel : StructureViewModel
{
}
public class ParentViewModel : StructureViewModel
{
public ParentViewModel()
{
Children = new List<ChildViewModel>();
}
public ICollection<ChildViewModel> Children { get; set; }
}
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
Parents = new List<ParentViewModel>();
var parent = new ParentViewModel { Name = "Parent" };
parent.Children.Add(new ChildViewModel
{
Name = "Child1"
});
parent.Children.Add(new ChildViewModel
{
Name = "Child2"
});
Parents.Add(parent);
}
public ICollection<ParentViewModel> Parents { get; set; }
}
要顯示此我用下面的標記:
<TreeView ItemsSource="{Binding Parents}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Name}">
<i:Interaction.Behaviors>
<local:CheckParentBehavior Children="{Binding Children}" />
</i:Interaction.Behaviors>
</CheckBox>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
,修復神奇的複選框是CheckParentBehavior:
public class CheckParentBehavior : Behavior<CheckBox>
{
public IEnumerable<StructureViewModel> Children
{
get { return (IEnumerable<StructureViewModel>)GetValue(ChildrenProperty); }
set { SetValue(ChildrenProperty, value); }
}
public static readonly DependencyProperty ChildrenProperty =
DependencyProperty.Register("Children", typeof(IEnumerable<StructureViewModel>), typeof(CheckParentBehavior), new PropertyMetadata(OnChildrenChanged));
protected override void OnAttached()
{
if (Children != null)
AssociatedObject.IsChecked = GetCheck(Children);
}
private static void OnChildrenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
{
foreach (var child in e.NewValue as IEnumerable<StructureViewModel>)
child.PropertyChanged += (_, args) => OnChildPropertyChanged(d as CheckParentBehavior, args);
}
}
private static void OnChildPropertyChanged(CheckParentBehavior behavior, PropertyChangedEventArgs args)
{
if (args.PropertyName == "IsChecked")
behavior.AssociatedObject.IsChecked = GetCheck(behavior.Children);
}
public static bool? GetCheck(IEnumerable<StructureViewModel> children)
{
if (children.All(c => c.IsChecked.GetValueOrDefault()))
return true;
else if (children.Any(c => c.IsChecked.GetValueOrDefault()))
return null;
else
return false;
}
}
什麼情況是,它偵聽的PropertyChanged每個孩子的事件,如果它改變了缺陷性質,它會相應地改變父母。
希望您可以使用一些此代碼來解決您的問題。
你可以在ViewModel邏輯中做到這一點,但如果「IsChecked」屬性名稱是可配置的,則上面的Beahvior可以重用。 –