WPF 工具包 DataGrid 复选框问题 [英] WPF Toolkit DataGrid Checkbox Issues

查看:17
本文介绍了WPF 工具包 DataGrid 复选框问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的希望有人能在这里帮助我.我的程序中有一个 DataGrid,它有一个复选框列.DataGrid 的 ItemsSource 是以编程方式加载的 DataSet.当我在 DataGrid 中选择几个项目然后滚动它时,我得到了一些非常奇怪的行为.例如,当我检查两个 CheckBox 时,它告诉我我选择了2",但是如果我在 DataGrid 中向上或向下滚动,数字会发生变化.如果我滚动回初始位置,它会返回到2 selected".听起来很奇怪,当我滚动框时,它似乎正在调用 Checked/Unchecked 事件......非常奇怪......

I'm really hoping someone can help me out here. I have a DataGrid in my program that has a checkbox column. The ItemsSource for the DataGrid is a DataSet loaded programmatically. When I select a couple of items in the DataGrid and then scroll it, I get some very odd behavior. For example, when I check two of the CheckBoxes, it tells me that I have "2 selected", but then if I scroll up or down in the DataGrid, the number changes. If I scroll back to the initial position it goes back to the "2 selected". As odd as it sounds, it seems like it's calling the Checked/Unchecked events when I scroll the box...very odd...

我在代码顶部定义了以下内容:

I have the following defined at the top of my code:

private DataSet MyDataSet;
int selected_count = 0;

然后我在我的方法中有以下代码将信息加载到数据集中:

Then I have the following code in my method to load the information into the DataSet:

MyDataSet = new DataSet();
DataTable tempDataTable = new DataTable();
MyDataSet.Tables.Add(tempDataTable);

DataColumn tempCol = new DataColumn("Checked", typeof(bool));
tempDataTable.Columns.Add(tempCol);

for (int i = 0; i < 50; i++)
{
    DataRow tempRow = tempDataTable.NewRow();
    tempDataTable.Rows.Add(tempRow);
    tempRow["Checked"] = false;
}

MyList.ItemsSource = MyDataSet.Tables[0].DefaultView;

我使用以下 XAML 将 IsChecked 属性绑定到名为Checked"的 DataColumn:

I have the IsChecked property binded to the DataColumn named "Checked" using the following XAML:

<dtgrd:DataGrid x:Name="MyList" AutoGenerateColumns="False" CanUserAddRows="False" CanUserResizeRows="False" HeadersVisibility="Column" SelectionUnit="FullRow" HorizontalGridLinesBrush="#FF688CAF" VerticalGridLinesBrush="#FF688CAF">
    <dtgrd:DataGrid.Columns>
        <dtgrd:DataGridTemplateColumn x:Name="CheckCol" CanUserSort="True" CanUserResize="False">
            <dtgrd:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox Name="MyCheckBox" IsChecked="{Binding Checked}" HorizontalAlignment="Center" VerticalAlignment="Center" Checked="MyCheckBox_Checked" Unchecked="MyCheckBox_Unchecked" />
                </DataTemplate>
            </dtgrd:DataGridTemplateColumn.CellTemplate>
        </dtgrd:DataGridTemplateColumn>
    </dtgrd:DataGrid.Columns>
</dtgrd:DataGrid>

然后,我通过选中/取消选中其中一个复选框来调用以下事件:

Then, I have the following events that are called by checking/unchecking one of the checkboxes:

private void MyCheckBox_Checked(object sender, RoutedEventArgs e)
{
    selected_count++;
    TxtSelectedCount.Text = "" + selected_count + " selected";
}

private void MyCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
    selected_count--;
    TxtSelectedCount.Text = "" + selected_count + " selected";
}

我也尝试过其他东西,但遇到了不同的错误.例如,我从 XAML 代码中删除了 Binding 并尝试使用以下 Checked/Uncheck 事件以编程方式设置它:

I have also tried other things, but get different bugs. For example, I removed the Binding from the XAML code and tried to set it programmatically using the following Checked/Uncheck events:

private void MyCheckBox_Checked(object sender, RoutedEventArgs e)
{
    DataRow tempRow = MyDataSet.Tables[0].Rows[MyList.Items.IndexOf(MyList.SelectedItems[0])];
    tempRow["Checked"] = true;

    selected_count++;
    TxtSelectedCount.Text = "" + selected_count + " selected";
}

private void MyCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
    DataRow tempRow = MyDataSet.Tables[0].Rows[MyList.Items.IndexOf(MyList.SelectedItems[0])];
    tempRow["Checked"] = false;

    selected_count--;
    TxtSelectedCount.Text = "" + selected_count + " selected";
}

当我使用该代码时,检查项目的数量保持不变,但实际检查在我滚动时移动到不同项目.

When I use that code, the number of checked items stays the same, but the actual checks move around to different items while I'm scrolling.

老实说,我不知道发生了什么,但这非常令人沮丧!任何帮助将不胜感激!

I honestly have no clue what's going on, but it's very frustrating! Any help would be GREATLY appreciated!

推荐答案

您遇到了物品容器回收问题.请参阅 http://blogs.msdn.com/b/vinsibal/archive/2008/05/14/recycling-that-item-container.aspx.WPF 在您滚动时重新使用行对象,您会看到 Checked 和 Unchecked 事件在它绑定到不同的行时触发.

You're running into item container recycling. See http://blogs.msdn.com/b/vinsibal/archive/2008/05/14/recycling-that-item-container.aspx. WPF is re-using the row objects as you scroll, and you're seeing the Checked and Unchecked events fire as it binds to a different row.

如果你想坚持你当前的解决方案,你可以禁用物品容器回收通过将 VirtualizingStackPanel.VirtualizationMode="Standard" 添加到您的 dtgrd:DataGrid 元素.您还可以通过添加 VirtualizingStackPanel.IsVirtualizing="False" 来完全禁用虚拟化.

If you want to stick with your current solution, you can just disable item container recycling by adding VirtualizingStackPanel.VirtualizationMode="Standard" to your dtgrd:DataGrid element. You could also disable virtualization entirely by adding VirtualizingStackPanel.IsVirtualizing="False".

更好的设计可能是从您的底层数据模型中获取数据,而不是依赖于 UI 事件.尝试处理 DataTable.ColumnChanged 事件数据表.

A better design might be to get that data from your underlying data model rather than relying on the UI events. Try handling the DataTable.ColumnChanged event on the DataTable.

这篇关于WPF 工具包 DataGrid 复选框问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆