繁体   English   中英

有没有办法防止更改 WPF DataGrid 中的选定行?

[英]Is there a way to prevent the change of the selected row in a WPF DataGrid?

我想确保在 wpf DataGrid 中始终选择最后一行(使用 MVVM)。 下面的代码绑定到一个按钮。 它选择 DataGrid 中的最后一行。 它完美地工作。

    private void SelectLastRow(object obj)
    {
        var temp = DisplayedRows.Last();
        selectedRow = temp;
        OnPropertyChanged(nameof(SelectedRow));
    }

如果我将相同的代码放入 SelectedRow 设置器(绑定到 DataGrid 的 SelectedRow 属性),它将不起作用。 设置器已执行,但在 GUI 上不是选择最后一行,而是我单击的那一行。 知道为什么吗? 如果 DataGrid 中存在验证错误,我的总体目标是防止行更改。

    private object selectedRow;
    public object SelectedRow
    {
        get => selectedRow;
        set
        {
            var temp = DisplayedRows.Last();
            selectedRow = temp;
            OnPropertyChanged(nameof(SelectedRow));
        }
    }

由于事件触发的顺序,这个有点复杂。 当您单击DataGrid时,将按列出的顺序发生以下事件。

  1. PreviewMouseDown
  2. SelectionChanged
  3. MouseLeftButtonUp

还有其他鼠标事件发生,但我们只会触及这些。 您的DataGrid.SelectionChanged事件将触发并更新您的 ViewModel 中的SelectedRow属性(如您所见),但由于接下来是MouseLeftButtonUp处理程序,它将覆盖您创建的选定行绑定。

private void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
   e.Handled = true;
}

但这实际上会阻止所有鼠标事件在 DataGrid 中触发(包括SelectionChanged事件),这可能是您不想要的。

由于您的目标是覆盖对某些项目的选择,因此您应该考虑改为绑定到DataGridRow.IsEnabled属性。 这样,可以在您的 ViewModel 中将其设置为false ,以在您选择时禁用验证错误的行选择。

例子

<DataGrid>
     <DataGrid.RowStyle>
           <Style TargetType="DataGridRow">
               <Setter Property="IsEnabled" Value="{Binding MyIsEnabledProperty}"/>
           </Style>
     </DataGrid.RowStyle>
</DataGrid>

@Tronald 和其他人提供了帮助。 我的目标是在出现验证错误时阻止更改行。 我使用IDataErrorInfo PreviewMouseLeftButtonDown事件后面的代码中,检查我是否想要 select 另一行。 如果是真的,那么我必须检查 dataGrid 中是否有错误。 Validation.GetHasError(parent)是不够的,因为它只检查 datGrid 而不是 DataGridRow-s。 我在行编辑结束时按 Enter。

private void DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var selectedItemNext = (e.OriginalSource as FrameworkElement).DataContext;
    var selectedItemNow = dataGrid.SelectedItem;
    if (selectedItemNext != selectedItemNow)
        if (!IsValid(sender as DependencyObject))
            e.Handled = true;
}    

public bool IsValid(DependencyObject parent)
{
    if (Validation.GetHasError(parent))
        return false;
    for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i)
        if (!IsValid(VisualTreeHelper.GetChild(parent, i)))
            return false;
    return true;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM