【问题标题】:Select another DataGrid row only if condition is satisfied - WPF仅在满足条件时才选择另一个 DataGrid 行 - WPF
【发布时间】:2020-02-27 05:18:52
【问题描述】:

我在 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));
}

但我无法获得所需的行为。

所以,总而言之,我希望只有在 用户确认它在消息框中被选中。其他旧选择 行只应保持选中状态。

【问题讨论】:

标签: c# wpf


【解决方案1】:

你可以试试这个,希望对你有帮助。

 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;
    }

【讨论】:

    【解决方案2】:

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

    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>
    

    【讨论】:

    • @ArpitGupta:你试过这个吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2021-08-25
    相关资源
    最近更新 更多