簡體   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