【问题标题】:WPF DataGrid toggle selection mode & Button in CellTemplateWPF DataGrid 切换选择模式和 CellTemplate 中的按钮
【发布时间】:2012-08-24 15:07:03
【问题描述】:

我正在构建一个 POS 应用程序,并且我希望最终用户能够对数据网格(即 I.E.)进行切换选择模式。他们可以单击多行,并且每个单击的项目都将累积在 SelectedItems 属性上 - 同样单击已选择的行将取消选择该行。我在另一个 stackoverflow 问题中找到了这段代码:

<DataGrid.Resources>
    <Style TargetType="{x:Type DataGridCell}">
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DoCheckRow" />
    </Style>
</DataGrid.Resources>

public void DoCheckRow(object sender, MouseButtonEventArgs e)
{
    DataGridCell cell = sender as DataGridCell;
    if (cell != null && !cell.IsEditing)
    {
        DataGridRow row = VisualHelpers.TryFindParent<DataGridRow>(cell);
        if (row != null)
        {
            row.IsSelected = !row.IsSelected;
            e.Handled = true;
            Debug.WriteLine(sender);
        }
    }
}

这实际上给了我想要的切换选择模式,但是,当我将按钮添加为 CellTemplate 时,单击时不会触发按钮命令,因为我在上面的代码中设置了 e.Handled = true;这停止了​​事件泡沫。有什么办法可以兼顾两者吗?

【问题讨论】:

    标签: wpf events toggle wpfdatagrid


    【解决方案1】:

    也许您可以尝试在按钮上添加 AttachedBehavior?这样您就可以从图片中获取命令并处理 AttachedBehavior 中的点击事件。

    【讨论】:

    • 好建议。我尝试了附加行为以及处理 Click 事件。它没有被调用。
    • 感谢您为我指明正确的方向!我能够使用命中测试和一些辅助函数来解决它来找到可视子/父。看我的回答
    【解决方案2】:

    您也可以使用一个复选框来执行此操作,该复选框将在相应行上切换选择。

    <DataGrid.RowHeaderTemplate>
       <DataTemplate>
          <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay,
                               RelativeSource={RelativeSource FindAncestor,
                               AncestorType={x:Type DataGridRow}}}"/>
       </DataTemplate>
    </DataGrid.RowHeaderTemplate>
    

    【讨论】:

      【解决方案3】:

      我能够通过使用一些辅助函数来查找可视子/父和一些命中测试来解决它:

      public void DoCheckRow(object sender, MouseButtonEventArgs e)
      {
          DataGridCell cell = sender as DataGridCell;
          if (cell != null && !cell.IsEditing)
          {
              DataGridRow row = VisualHelpers.TryFindParent<DataGridRow>(cell);
              if (row != null)
              {
                  Button button = VisualHelpers.FindVisualChild<Button>(cell, "ViewButton");
      
                  if (button != null)
                  {
                      HitTestResult result = VisualTreeHelper.HitTest(button, e.GetPosition(cell));
      
                      if (result != null)
                      {
                          // execute button and do not select / deselect row
                          button.Command.Execute(row.DataContext);
                          e.Handled = true;
                          return;
                      }
                  }
      
                  row.IsSelected = !row.IsSelected;
                  e.Handled = true;
              }
          }
      }
      

      虽然它不是最优雅的解决方案,但它适用于我使用的 MVVM 模式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-04
        • 1970-01-01
        • 2016-11-14
        相关资源
        最近更新 更多