1

我在 a 中有一个数据绑定CheckBoxDataGrid使用 WPF 和 MVVM;

<DataGridTemplateColumn Width="80" Header="Enabled">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Path=IsEnabled, UpdateSourceTrigger=PropertyChanged,  Mode=TwoWay}" Name="theCheckbox" HorizontalAlignment="Center"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

这工作正常,并且在设置CheckBox时正在检查IsEnabledIsEnabled是我绑定到的对象集合中的一个属性DataGrid。我想要做的是能够验证是否应该允许在用户选择它时检查其中的特定行CheckBoxDataGrid如果不删除他们的检查并显示警告消息,例如“没有第 5 行就无法检查第 1 行和 9 个正在检查”。我发现了如何使用后面的代码使用Checked和的Unchecked属性来执行此操作CheckBox,但是我正在使用 MVVM,因此想要处理ViewModel与 ViewDataGrid和相关联的事情CheckBox。我该怎么做?我需要一种传递 Id 字段的方法DataRow为了确定我正在处理哪一行,为了论证,我们可以说 Id 字段被调用BorderId

4

3 回答 3

1

在您的对象上实现IDataErrorInfo,这是 WPF 的默认验证接口,并设置您的验证代码以验证是否可以选中复选框

这实际上比正常情况要复杂一些,因为您正在使用数据项上不存在的数据来验证数据项上的属性,这意味着您需要提供某种方式在运行时将不相关的验证附加到您的对象。

我通常使用的解决方案是从我的对象中公开一个 ValidationDelegate,其他对象可以使用它来为对象附加额外的验证。它的代码发布在我的博客上,它允许您将验证附加到您的对象,如下所示:

public class MyViewModel
{
    // Keeping this generic to reduce code here, but it
    // should be a full property with PropertyChange notification
    public ObservableCollection<SomeObject> SomeCollection { get; set; }

    public MyViewModel()
    {
        SomeCollection = LoadDataGridObjects();

        // Add the validation delegate to each object
        foreach(var item in SomeCollection)
            item.AddValidationDelegate(ValidateObject);
    }

    // Validation Delegate to verify the right checkboxes are checked
    private string ValidateObject(object sender, string propertyName)
    {
        if (propertyName == "IsChecked")
        {
            var item = (SomeObject)sender;
            if (item.Id == 1
                && !SomeCollection.First(p => p.Id == 5).IsChecked
                && !SomeCollection.First(p => p.Id == 9).IsChecked)
            {
                return "Row 1 cannot be checked without rows 5 and 9 being checked";
            }
        }
        return null;
    }
}
于 2012-11-07T17:40:52.020 回答
0

您可以添加到列表中每个项目的 PropertyChanged 事件处理程序吗?像这样的东西:

foreach (Object x in List)
{
    x.PropertyChanged += OnItemChanged;
}

然后在更改侦听器中,您可以对发送者对象执行任何您喜欢的操作,包括更改 IsEnabled 属性。

void OnItemChanged(object sender, PropertyChangedEventArgs e)
{
    // change sender object properties or set bound label text here
}
于 2012-11-07T17:04:10.403 回答
0

如果我理解你的问题,你有一个复选框,你想控制它是否可以被选中。如果您不想允许,不要让用户一直检查它并推回错误消息,如果您不希望用户检查它,请首先使您的复选框处于非活动状态。

要通过您的 ViewModel(当然是您的 DataContext)执行此操作,您需要将 Checkbox 的“命令”绑定到您的 ViewModel 中的自定义命令。

WPF 命令将提供以下功能:

  • 根据自定义逻辑自动启用/禁用控件
  • 处理控件的“动作”事件(在复选框的按钮上,它将是“单击”)。
于 2012-11-07T17:29:05.323 回答