2013-04-08 56 views
3

在视图,即XAML,我已在全选布尔值绑定到CheckBox控件在WPF/MVVM,如何实现以完美的方式

<CheckBox Grid.Row="5" Content="Select All" HorizontalAlignment="Left" Margin="0,5, 0, 0" IsChecked="{Binding Path=SelectAll, Mode=TwoWay}" Width="206"></CheckBox> 

“全选”功能和fullfill的全选作为

public bool SelectAll 
    { 
     get { return this.Get<bool>("SelectAll"); } 
     set 
     { 
      this.Set<bool>("SelectAll", value); 
      if (this.SelectAllCommand.CanExecute(null)) 
       this.SelectAllCommand.Execute(value); 
     } 
    } 

是的,它看起来不错,但我有一个问题...

当所有的复选框被手动选择,在全选复选框应自动选择......在那个时候,我们不不想要SelectAllCommand要执行的命令......

我该怎么办呢.....我知道也许这是一件容易的事,但如何完美地做到这一点....

谢谢你给我一些提前

+0

你一定希望SelectedAll属性是可空 Aron 2013-04-08 07:15:36

+0

BTW是什么this.Set/this.Get? – Aron 2013-04-08 07:21:46

+0

他只是想“当所有的复选框手动选择,...”,所以这是一个很好的问题+1。确定它可以在ObservableCollection Source.CollectionChanged事件上实现。但这个问题寻找最佳做法。 – 2013-04-08 07:22:51

回答

1

建议尝试

public bool? SelectedAll 
{ 
    get { return this.Get<bool?>("SelectedAll"); } 
    set 
    { 
     if(Equals(SelectedAll, value) == true) 
      return; 
     this.Set<bool?>("SelectedAll", value); 
     OnSelectedAllChanged(value); 
    } 
} 

private void SelectedAllChanged(bool? input) 
{ 
    //Stuff 
} 
+0

你如何管理手动选择所有元素。那么SelectAll的状态会是什么? – 2013-04-08 07:24:23

+0

哦,谢谢你的建议,但是我的领导真的不喜欢可空值,也许代码不会通过他的评论。 :( – Miyazaki 2013-04-08 07:39:04

+1

它不是一个喜欢或不喜欢的情况,这实际上是一个三态,你可以有所有选择/全部未选择/混合。硬性快速规则,如“我不喜欢可空,所以应该有none“是不好的,这是一个三态的商业案例,所有的代码都需要知道三态,替代方案是使用三态枚举 – Aron 2013-04-08 07:48:22

0

你需要使用PropertyChanged事件项目的重新评估SelectAll值随时选择一个项目。

例如,

// Setup PropertyChange notification for each item in collection 
foreach(var item in MyCollection) 
{ 
    item.PropertyChanged += Item_PropertyChanged; 
} 

private bool _isSelectAllExecuting = false; 

// If the IsSelected property of an item changes, raise a property change 
// notification for SelectAll 
void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if (!_isSelectAllExecuting && e.PropertyName == "IsSelected") 
     ReevaluateSelectAll(); 
} 

void ReevaluateSelectAll() 
{ 
    // Will evaluate true if no items are found that are not Selected 
    _selectAll = MyCollection.FirstOrDefault(p => !p.IsSelected) == null; 

    // Since we're setting private field instead of public one to avoid 
    // executing command in setter, we need to manually raise the 
    // PropertyChanged event to notify the UI it's been changed 
    RaisePropertyChanged("SelectAll"); 
} 

void SelectAll() 
{ 
    _isSelectAllExecuting = true; 

    foreach(var item in MyCollection) 
     item.IsSelected = true; 

    _isSelectAllExecuting = false; 
} 
+0

我不明白当所有选择的项目触发时如何管理Selectall->所以,当SelectAll“Select All items Action”---继续时,Stack Over Flow会发生,也许我们需要一些布尔或类似的东西来处理手动或自动选择的SelectAll – 2013-04-09 05:46:34

+0

@DavutGürbüz通常我的setter会检查if (_field!= value)',只更新私有字段并在值发生变化时引发'PropertyChange'通知。从'true'更改为'true'不应引发'PropertyChange'通知。它会提高PropertyChange noti过于频繁。在这些情况下,我倾向于使用私人布尔来禁用通知,而一切都在更新(我会更新我的答案) – Rachel 2013-04-09 11:56:15

相关问题