WPF 数据表格单元格、单元格信息和选定单元格 + 自定义选择

5

我想在WPF datagrid中操作选择,但是我在访问实际单元格、设置焦点和标记为选定时遇到了问题。

  1. 有人能解释一下为什么没有一种简单的方法可以从DatagridCellInfo中获取DatagridCell吗?
  2. 为什么几乎没有人在SO上使用WPF datagrids?(我没有看到很多得票的Q/A)
  3. 是否有一种简单的方法来为WPF datagrid创建自己的选择模式?

我的问题

我想在WPF Datagrid上进行自定义选择,当选择更多单元格(逐个)而不按Ctrl键时。我做得很好,但是当我想取消选定其中一个单元格时,就会出现问题-只需单击即可。将其从列表中删除并不是问题。问题在于,当它被单击时,它会获得焦点并高亮显示,并且所有其他已选单元格都会关闭其高亮显示。如果我选择另一个未被选中的单元格,则所有选定的单元格都会再次正确地突出显示。问题只出现在取消选择中。

我的代码:

XAML:

<Window x:Class="SelectionTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="DataGridCell">
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown"></EventSetter>
                                
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="Pink"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <DataGrid 
            Name="mydatagrid"
            Width="Auto" Height="Auto"
            HeadersVisibility="All"
            AutoGenerateColumns="True" IsReadOnly="True"
            SelectionMode="Extended" SelectionUnit="Cell" 
            CanUserAddRows="False" CanUserDeleteRows="False"
            CanUserResizeColumns="False" CanUserResizeRows="False" 
            CanUserReorderColumns="False" CanUserSortColumns="False"
            SelectedCellsChanged="mydatagrid_SelectedCellsChanged"
            Padding="10" HorizontalAlignment="Center" VerticalAlignment="Top"
            >            
        </DataGrid>  
    </Grid>
</Window>

我已经用我创建的一些随机示例类对象填充了datagrid。

C#:

        private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DataGridCell cell = sender as DataGridCell;
            
            DataGridCellInfo cellInfo = new DataGridCellInfo(cell);

            if ((cell.IsSelected)||(selectedList.Contains(cellInfo))||(selectedCellsList.Contains(cell)))
            {
                selectedList.Remove(cellInfo);
                selectedCellsList.Remove(cell);
                cell.IsSelected = false;
                mydatagrid.CurrentCell = selectedList[0];
            }
            else
            {

               if (selectedList.Count < 7)
               {
                   selectedList.Add(cellInfo);
                   selectedCellsList.Add(cell);
               }
               else
               {
                  selectedList.RemoveAt(0);
                  selectedList.Add(cellInfo);
                  selectedCellsList.RemoveAt(0);
                  selectedCellsList.Add(cell);
               }
            }
            
            mydatagrid.SelectedCells.Clear();
            mydatagrid.UnselectAll();

            foreach (DataGridCell xcell in selectedCellsList)
            {
                xcell.IsSelected = true;
                xcell.Focus();
            }
}

如果这段代码看起来很丑陋,那我很抱歉。但我还只是一个小的csharpawan。

我的问题简述: 点击选定的单元格只会使其突出显示和聚焦,并且取消所有其他选定的单元格的高亮显示,这正好与我想要的相反。(如果我点击其他未选择的单元格,则它按照我想要的方式工作。)


答案2:使用ItemsControl制作自定义控件并实现所需的自定义逻辑要容易得多。 - Terry
这也是问题#3的答案吗?因为我只想选择除了在单元格上按Ctrl +单击之外的其他方式..以及选择先前保存的单元格.. - Ms. Nobody
当然,如果您不想使用ctrl-click进行多选,您可以创建自己的列表并实现任何多选方式。您希望用户如何进行多选? - Terry
我想要通过单击单元格来选择扩展模式,这样我就可以选择更多的单元格而不仅仅是一个,现在如何在没有按下Ctrl键的情况下实现呢?我还想最多选择7个单元格。如果超过了这个数量,第一个将被取消选择。我尝试使用MouseLeftButtonDown事件来解决这个问题,几乎已经解决了。只是在取消已经单击的单元格时遇到了问题。 - Ms. Nobody
1
完全可行,让我快速构建一些东西! - Terry
1个回答

44

问题1的答案:从DataGridCellInfo快速获取DataGridCell的方法:

    public DataGridCell GetDataGridCell(DataGridCellInfo cellInfo)
    {
        var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
        if (cellContent != null)
            return (DataGridCell) cellContent.Parent;

        return null;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接