我对整个 WPF 和 MVVM 想法比较陌生,我正在寻找有关最佳实践的建议。我有一个可行的解决方案,但感觉我可能缺少一些可以简化整个事情的出色 XAML 语法。
我在存储为 CSV 的数据库表中有一个字符串字段,例如“CAT, DOG”。也许我应该在我的实体数据模型中将其作为多对多关系来完成,但这是一个不同的最佳实践讨论。
在我的 XAML 中,我在包含 CheckBoxes 的 ListBox 上使用了多重绑定。可能选择的范围在运行时确定,ListBox 使用 DataTemplate 生成 CheckBox。这是 XAML:
<ListBox Grid.Column="3" Grid.Row="8" Grid.RowSpan="2" Name="brandedProductsListBox" Margin="3" ItemsSource="{Binding Source={StaticResource brandedProductLookup}}" IsSynchronizedWithCurrentItem="True" TabIndex="475">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Margin="3" Content="{Binding Path=BrandedProductName}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked">
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource brandedProductToBoolean}">
<Binding Source="{StaticResource projectsView}" Path="BrandedProducts" />
<Binding Path="BrandedProductName" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
我使用转换器来检查适当的复选框。我试图让转换器的 ConvertBack 方法将布尔值转换为我的 CSV 字符串,但是当我传递的只是一个布尔值时,我无法弄清楚如何访问哪个BrandedProductName。这是转换器:
public class BrandedProductToBooleanConverter : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) {
return false;
}
else {
// The bindings passed in (in order) are: the BrandedProducts field for the current project,
// and the Branded Product represented by the current CheckBox.
string brandedProducts = value[0] as string;
string brandedProduct = value[1] as string;
return brandedProducts == null ? false : brandedProducts.Contains(brandedProduct);
}
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
return null;
}
}
So Convert properly checks the right CheckBoxes when an entity is selected, but when adding a new one I figured out I could use the Checked and UnChecked event handlers of the CheckBox to write back to my entity, like so:
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
if (projectView.IsAddingNew) {
CheckBox checkBox = sender as CheckBox;
NewProject project = projectView.CurrentAddItem as NewProject;
if (project.BrandedProducts == null) {
project.BrandedProducts = (string)checkBox.Content;
}
else {
project.BrandedProducts += ", " + (string)checkBox.Content;
}
}
e.Handled = true;
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
if (projectView.IsAddingNew) {
CheckBox checkBox = sender as CheckBox;
NewProject project = projectView.CurrentAddItem as NewProject;
if (project.BrandedProducts != null) {
project.BrandedProducts = project.BrandedProducts.Replace((string)checkBox.Content + ", ", "").Replace(", " + (string)checkBox.Content, "");
}
}
e.Handled = true;
}
如果你还和我在一起,问题是什么是更好的方法来做到这一点?感觉有点像苹果和橘子,我使用转换器从实体生成视图,然后使用事件处理程序将视图更新/命令转换回实体。以这种方式使用事件处理程序修改我的 ViewModel 是否违反了 MVVM 的某些目标?
提前感谢您的任何建议,雷