数据上下文类:
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个复选框绑定到每个数组成员。 Click事件处理程序根据新的directions
数组状态重新计算图像。如何更改此代码以删除CheckBox_Click
事件处理程序,使其按照MVVM模式工作?我需要一种方法来检测directions
数组中的更改,而无需编写事件处理程序。
答案 0 :(得分: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所属的Data,以及这两者之间的中间层(ViewModel)。因此,只要您将逻辑保留在ViewModel中(通过在事件处理程序中委托ViewModel.DoSomething()
),您当前基于事件的方法不会破坏MVVM。
答案 1 :(得分:1)
然后WPF复选框具有Command属性,您可以将其绑定到视图模型中的ICommand(使用RelayCommand),并且还传递参数以查看哪个复选框(在您的情况下为绑定项)已更新。
我的另一个建议是改变XAML,如果你确定你的viewmodel会决定你的UniformGrid中显示什么,即它是否总是从viewmodel呈现数据,那么你也可以在你的UniformGrid中定义ItemsControl,然后定义一个ItemTemplate的模板,这样你也不需要在XAML中将你的复选框与定义的索引绑定,而不是在以后维护它