仅在满足条件的情况下选择另一个DataGrid行-WPF

时间:2020-02-27 05:18:52

标签: c# wpf

我在WPF中有一个DataGrid。

我遇到的情况是,如果选择了一行,然后用户选择了另一行,则应该出现类似-

的消息

确定要选择吗?

如果用户说是,则仅应选择另一行。

但是,在当前情况下,SelectionChanged事件已被调用,并且选择了新行。

我尝试使用一些属性绑定

<Style TargetType="DataGridRow">
     <Setter Property="IsEnabled" Value="{Binding IsToEnableRowSelection, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"/>                        
</Style>

在后端-

private void MyDataGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (MessageBox.Show("Are you sure you want save changes?", "Confirm", MessageBoxButtons.YesNo))
    {
        e.Handled = false;
        IsToEnableRowSelection = true;
    }
    else
    {
        e.Handled = true;
        IsToEnableRowSelection = false;
    }
}

带有INotify事件的属性声明-

public bool IsToEnableRowSelection
{
    get
    {
        return enableSelectedRow;
    }
    set
    {
        enableSelectedRow = value;
        OnPropertyChanged("IsToEnableRowSelection");
    }
}

protected void OnPropertyChanged([CallerMemberName()] string name = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

但是我无法获得想要的行为。

因此,总而言之,我希望仅在以下情况下才选择新行: 用户确认在消息框中被选中。其他旧选 行应保持选中状态。

2 个答案:

答案 0 :(得分:0)

您可以尝试一下,希望对您有所帮助。

 Object _SelectedItem; //_SelectedItem is used to avoid the repeated loops
    DataGridCell _FocusedCell; //_FocusedCell is used to restore focus
    private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

        if (_SelectedItem == MyDataGrid.SelectedItem)
        {
            return;
        }
        _SelectedItem = MyDataGrid.SelectedItem;


        if (e.RemovedItems.Count > 0 && e.RemovedItems[0] != null && MessageBox.Show("Are you sure you want save changes?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
        {

            _SelectedItem = e.RemovedItems[0];
            Dispatcher.BeginInvoke(
              new Action(() =>
              {
                  MyDataGrid.SelectedItem = e.RemovedItems[0];
                  if (_FocusedCell != null)
                  {
                      _FocusedCell.Focus();
                  }
              }), System.Windows.Threading.DispatcherPriority.Send); //hope a high priority can avoid flicking.
        }
    }

    private void DataGridCell_LostFocus(object sender, RoutedEventArgs e)
    {
        _FocusedCell = sender as DataGridCell;
    }

答案 1 :(得分:0)

您可以为PreviewMouseLeftButtonDown处理DataGridRow事件,如下所示:

private void DataGridRow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (dg.SelectedItem != null)
    {
        e.Handled = true;

        HitTestResult hitTestResult = VisualTreeHelper.HitTest(dg, e.GetPosition(dg));
        DataGridCell cell = FindParent<DataGridCell>(hitTestResult.VisualHit);

        if (MessageBox.Show(this, "confirm....?", "caption..:", MessageBoxButton.YesNoCancel) == MessageBoxResult.Yes)
        {
            dg.SelectedItem = cell.DataContext;
            cell.Focus();
        }
    }
}

XAML:

<Style TargetType="DataGridRow">
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridRow_PreviewMouseLeftButtonDown" />
</Style>