【问题标题】:How do I figure out if a row in a DataGridCheckBoxColumn is checked in a DataGrid?如何确定 DataGridCheckBoxColumn 中的行是否在 DataGrid 中被选中?
【发布时间】:2012-08-19 06:06:11
【问题描述】:

如果我在 DataGrid 中有一个 DataGridCheckBoxColumn(而不是使用数据网格的多选模式),我如何跟踪或发现哪些行已被检查?

DataGrid 中是否有合适的属性来枚举每一行并检查列? DataGrid.ItemsSource 将为我提供基础集合 - 我希望能够自己获取网格行项目中的列

如果我响应 CheckBox 的 Click 事件,我如何确定该 CheckBox 属于基础集合中哪个项目的哪一行?

<DataGrid x:Name="dgPlayers" AutoGenerateColumns="False" Height="450" CanUserAddRows="False" AlternationCount="2" AlternatingRowBackground="WhiteSmoke" GridLinesVisibility="None">
                <DataGrid.Columns>
                    <DataGridCheckBoxColumn></DataGridCheckBoxColumn>
                    <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Position" Binding="{Binding Path=PositionCode, Converter={StaticResource NFLPositionGrouper}}"></DataGridTextColumn>
                    <DataGridTextColumn Header="College" Binding="{Binding Path=CollegeName}"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>

如您所见,我没有将 DataGridCheckBoxColumn 绑定到任何属性 - 我的目的是使用它进行选择(是的,我知道,DataGrid 已经内置了多项选择......这纯粹是一个学术练习)

【问题讨论】:

  • 你的 DataGrid 是如何获得它的行的?带绑定?到什么?显示 Xaml。我的想法是:迭代你绑定的对象怎么样?
  • 通过将代码隐藏中的 ItemsSource 设置为对强类型对象的 LINQ to Entities 查询来填充网格 - 没什么特别的。迭代集合中的对象如何让我访问相应的 DataGrid 行?
  • 在后面的代码中,使用公共属性引发 PropertyChange,它是存储类的 List(或其他 IEnumerable)。然后在某个时刻你用 Linq Query 填充它。在 Xaml 中,您将 ItemSource 绑定到属性。因此,您可以随时使用该属性访问任何行的值。
  • 你能发布你的 xaml 控件吗?您应该将复选框列绑定到您的实际 DTO。由于它们已绑定,您应该能够查看您的实际数据收集以查看已检查或未检查的内容
  • 已发布。我没有将 CheckBox 列绑定到绑定对象的任何属性......不过,这是一个很好的观点。我主要来自 ASP.NET 背景,因此我想利用这个示例来熟悉导航网格行的对象层次结构,并在需要时访问每个网格行内的各个控件

标签: c# .net wpf


【解决方案1】:

你可以试试这样的

 foreach (GridViewRow row in yourgrid.Rows)
    {
        Access the CheckBox
        CheckBox cb = (CheckBox)row.FindControl("youcheckboxid");
        if (cb != null && cb.Checked==true)
        {

          //you should now know the row where the checkbox was cheked 
         }
    }

【讨论】:

  • 视情况而定,理想情况下,我建议使用会触发事件的按钮来检查检查了哪些行
  • 对不起,我应该提一下 - 这是一个 WPF DataGrid,而不是一个 ASP.NET。事实上,最初我想用“WPF -”标记我的问题,但其他人冒昧地从我发布的另一篇文章的标题中删除了它,因为我已经用 WPF 关键字标记了它
【解决方案2】:

虽然我无法弄清楚如何枚举每个 DataGridRow,就像您在 ASP.NET 中通过 .Rows 集合可以做到的那样,但我意识到这无论如何都不是一个好主意,并且Microsoft 可能有意省略了此属性。

这是因为 DataGrid 与许多其他列表控件一样使用 UI 虚拟化,这意味着它只会为 VISIBLE 行生成 DataGridRow 项 - 如果您可以枚举每一行,这将违背此功能的目的并不必要地消耗内存.

正如许多人所提到的(我并不反对),最终最好的方法是按照 MS 的意图使用网格,这是一种面向对象的方式,绑定到可以直接访问它的底层对象。

但是,我确实找到了一些接近我想要的东西,这确实让我可以访问实际的 DataGridRow 对象:

myDataGridInstance.ItemContainerGenerator.ContainerFromItem()

或者

myDataGridInstance.ItemContainerGenerator.ContainerFromIndex()

这两种方法都会为您提供与指定集合对象相对应的 DataGridRow,之后您可以剖析和导航它的可视化树和属性(例如,它自己的 DataContext 将是集合项实例),就像您期望的任何其他普通元素一样

我发现跟踪所有 CheckBox 刻度的另一种方法是通过 Control.Tag 属性关联底层对象绑定 - 我会将其设置为 {Binding} ,它只是将其绑定到底层集合对象本身,而不是特定属性...在 CheckBox 的事件处理程序中,我可以手动跟踪已选中/未选中的项目列表。

这绝对不是一个聪明的方法——但它是可能的,这就是我一直在寻找的——话虽如此,我现在将回到 MS 打算让我们做的事情:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多