c# - ValidationRule:在datagrid WPF C#中获取选定的组合框行号
问题描述
我创建了一个数据网格,其中每一行代表我们实验室中一台机器的命令。我想通过在我的代码中实现验证规则来限制用户在“限制模式”列中选择“相对”的选项。仅当与此行关联的移动控件和前一行相同时,用户才能使用“相对”限制模式(见图)。否则一条消息应该警告他。
我设法创建了一个有效的 RowValidationRules:
XAML:
<DataGrid.RowValidationRules>
<utility:RelativeLimitModeRule ValidationStep="UpdatedValue"/>
</DataGrid.RowValidationRules>
验证规则:
class RelativeLimitModeRule : ValidationRule
{
//Makes sure that if "Relative" move position is selected, the previous command had the same MoveCtrl (otherwise relative is bullshit)
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value is BindingGroup bg && bg.Items.Count > 0)
{
if ((bg.Items[0] as DoliInput).LimMode == "Relative")
{
if (bg.Owner is DataGridRow dgrow)
{
DataGrid dg = GetParent<DataGrid>(dgrow);
int currItemKey = ((bg.Items[0]) as DoliInput).SequenceNumber - 1;
if (currItemKey > 0)
{
if (((((InteractiveGraph.MVVM.ViewModel)dg.DataContext).DoliInputCollection)[currItemKey - 1]).MoveCtrl != (bg.Items[0] as DoliInput).MoveCtrl)
{
return new ValidationResult(false, $"To use the \"Relative\" option, the previous command should have the same Move Ctrl as this one ");
}
}
}
}
}
return ValidationResult.ValidResult;
//return new ValidationResult(true, null);
}
private static T GetParent<T>(DependencyObject d) where T : class
{
while (d != null && !(d is T))
{
d = VisualTreeHelper.GetParent(d);
}
return d as T;
}
}
我的模型在哪里DoliInput
,具有四个不同的属性:MoveCtrl
、和最后一个不可见的属性Speed
,它跟踪命令的位置,其中存储/列出要由机器处理的所有命令。但是,以这种方式实现时,验证规则仅在用户选择另一行并修改“Spe”列时触发。LimitMode
SequenceNumber
DoliInputCollection
ObservableCollection
我修改了 XAML,因此只要用户选择“相对”作为限制模式,验证规则就会触发:
新的 Xaml:
<DataGridTemplateColumn Header="Limit Mode">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding LimModeItem}">
<ComboBox.SelectedItem>
<Binding Path="LimMode"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<utility:RelativeLimitModeRule>
</utility:RelativeLimitModeRule>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding LimModeItem}"
SelectedItem="{Binding LimMode, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
但是现在value
验证规则中的参数返回选择字符串,并且我无法访问在当前行移动控件和前一个行之间进行比较所需的行索引。
使用 Combobox_DropDownOpened 事件,我能够检索行索引。
private void ComboBox_DropDownOpened(object sender, EventArgs e)
{
var cb = ((System.Windows.Controls.ComboBox)sender);
DataGridRow dataGridRow = VisualHelper.FindParent<DataGridRow>(cb);
int index = dataGridRow.GetIndex();
}
但我想保持我的 CodeBehind 清晰。因此,我尝试使用 Interactivity 将命令绑定到 DropDownEvent,但我不知道如何像使用事件那样处理发送方。
我走对了吗?如果是这样,我该如何使用命令检索行号?有没有更好的设置验证规则?
解决方案
好吧,ValidationStep="UpdatedValue"
不仅定义了何时触发验证规则,而且它还对value
发送到验证规则有影响。
通过从
<DataTemplate>
<ComboBox ItemsSource = "{Binding LimModeItem}" >
< ComboBox.SelectedItem >
< Binding Path="LimMode"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<utility:RelativeLimitModeRule/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
</DataTemplate>
到
<DataTemplate>
<ComboBox ItemsSource = "{Binding LimModeItem}" >
< ComboBox.SelectedItem >
< Binding Path="LimMode"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<utility:RelativeLimitModeRule ValidationStep="UpdatedValue"/ >
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
</DataTemplate>
参数的类型value
从string
变为BindingExpression
。从那里,我可以找到行索引。
推荐阅读
- windows - 即使在系统变量中设置路径后,也无法在命令提示符中执行 git 命令
- flutter - 关于 Flutter 中的 `native` 关键字
- postgresql - Informatica:更新 postgresql 数据库的时间太长
- angular - “ SyntaxError: Unexpected token { ” 尝试在 VS 代码中调试 Angular 8 的单元测试时
- video - 将输出帧率限制为最大 30
- c++ - 为什么一个
从模板类切换时出现? - azure - 如何在对话框启动时将外部状态传递给对话框?
- java - 对于 6 个元素,并行流比 for 循环花费更多时间
- java - JdbcTemplate 在 Spring Boot 中没有为 H2 数据库自动装配
- ios - 相机控制器关闭在 iOS Swift 中不起作用?