2013-08-18 37 views
1

数据上下文类复选框:如何删除点击处理程序绑定到bool []数组

class ImageHandler : INotifyPropertyChanged 
{ 
    bool[] directions = new bool[8]; 

    public bool[] Directions { get { return directions; } } 

    // ... 
} 

XAML:

<UniformGrid Columns="8"> 
    <CheckBox Content=" N" IsChecked="{Binding Path=Directions[0]}" Click="CheckBox_Click"/> 
    <CheckBox Content="NW" IsChecked="{Binding Path=Directions[1]}" Click="CheckBox_Click"/> 
    <CheckBox Content=" W" IsChecked="{Binding Path=Directions[2]}" Click="CheckBox_Click"/> 
    <!-- ... --> 
</UniformGrid> 

后面的代码:

private void CheckBox_Click(object sender, RoutedEventArgs e) 
{ 
    imageHandler.UpdateImage(); 
} 

所以,我有数据上下文类中的布尔数组以及绑定到每个数组成员的8个复选框。根据新的directions阵列状态,单击事件处理程序重新计算图像。我如何更改此代码以删除CheckBox_Click事件处理程序,使其按照MVVM模式工作?我需要一种方法来检测在directions数组中发生的更改,而无需编写事件处理程序。

+3

你想在viewmodel中处理点击复选框吗?然后,WPF复选框具有Command属性,您可以将其绑定到视图模型中的ICommand(使用RelayCommand)并传递参数以查看更新了哪个复选框(在您的案例绑定项目中)。 – whoisthis

+0

我的另一个建议是改变XAML,如果你确定你的viewmodel将决定在你的UniformGrid中显示什么,也就是说它总是呈现viewmodel的数据,那么你也可以在你的UniformGrid中定义ItemsControl,然后定义一个模板ItemTemplate,这样你也不需要将你的复选框与XAML中定义的索引绑定在一起,以后不再维护它 – whoisthis

+0

@bjoshi - 对我来说实现ICommand是可以的,发布这个命令作为答案,我会接受它。 –

回答

1

然后WPF复选框具有Command属性,您可以将它绑定到ICommand在您的视图模型(使用RelayCommand)并传递参数以查看哪个复选框(在您的大小写绑定项目中)已更新。

我的另一个建议是改变XAML,如果你确定你的viewmodel会决定你的UniformGrid中显示的是什么,也就是说它总是呈现viewmodel的数据,那么你也可以在你的UniformGrid中定义ItemsControl,然后定义ItemTemplate的一个模板,这样你也不需要将你的复选框与XAML中定义的索引绑定在一起,并且以后不再维护它

1

您需要为此使用ItemsControl。它消除了在XAML中逐个手动添加UI元素的需求,并且不需要事件处理程序。

视图模型:

class ImageHandler : INotifyPropertyChanged 
{ 
    List<Direction> directions = new List<Direction>(); 
    public List<Direction> Directions { get { return directions; } } 
    // ... 

    public ImageHandler() 
    { 
     Directions.Add(new Direction {DisplayName = " N" }); 
     Directions.Add(new Direction {DisplayName = "NW" }); 
     Directions.Add(new Direction {DisplayName = " W" }); 
     //.. Etc 

     Directions.ForEach(x => x.OnIsSelectedChanged = OnDirectionSelectionChanged); 
    } 

    private void OnDirectionSelectionChanged(Direction direction) 
    { 
     //.. Your logic here 
    } 
} 

数据项:

public class Direction: INotifyPropertyChanged 
{ 
    private bool _isSelected; 
    public bool IsSelected 
    { 
     get { return _isSelected; } 
     set 
     { 
      _isSelected = value; 
      if (OnIsSelectedChanged != null) 
       OnIsSelectedChanged(this); 

      NotifyPropertyChange(() => IsSelected); 
     } 
    } 

    public string DisplayName {get;set;} 

    public Action<Direction> OnIsSelectedChanged {get;set;} 
} 

XAML:

<ItemsControl ItemsSource="{Binding Directions}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Columns="8"/> 
     </ItemsPanelTemplate>  
    </ItemsControl.ItemsPanel> 

    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding DisplayName}" IsChecked="{Binding IsSelected}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

旁注:MVVM是不是无代码的背后,也不删除事件处理程序。这是关于把UI放在UI所属的位置,以及Data位于哪里的数据,以及这两者之间的中间层(ViewModel)。因此,只要您保留ViewModel中的逻辑(通过在事件处理程序中委托类似ViewModel.DoSomething()),您当前的基于事件的方法不会中断MVVM。

相关问题