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

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

问题描述

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



我将以下定义在我的代码的顶部:

  private DataSet MyDataSet; 
int selected_count = 0;

然后,我的方法中有以下代码将信息加载到DataSet中:

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

DataColumn tempCol = new DataColumn(Checked,typeof(bool));
tempDataTable.Columns.Add(tempCol); (int i = 0; i <50; i ++)
{
DataRow tempRow = tempDataTable.NewRow();


tempDataTable.Rows.Add(tempRow);
tempRow [Checked] = false;
}

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

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

 < dtgrd:DataGrid x:Name =MyListAutoGenerateColumns =FalseCanUserAddRows =FalseCanUserResizeRows =FalseHeadersVisibility = ColumnSelectionUnit =FullRowHorizo​​ntalGridLinesBrush =#FF688CAFVerticalGridLinesBrush =#FF688CAF> 
< dtgrd:DataGrid.Columns>
< dtgrd:DataGridTemplateColumn x:Name =CheckColCanUserSort =TrueCanUserResize =False>
< dtgrd:DataGridTemplateColumn.CellTemplate>
< DataTemplate>
< CheckBox Name =MyCheckBoxIsChecked ={Binding Checked}Horizo​​ntalAlignment =CenterVerticalAlignment =CenterChecked =MyCheckBox_CheckedUnchecked =MyCheckBox_Unchecked/>
< / DataTemplate>
< / dtgrd:DataGridTemplateColumn.CellTemplate>
< / dtgrd:DataGridTemplateColumn>
< / dtgrd:DataGrid.Columns>
< / dtgrd:DataGrid>

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

  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事件以编程方式进行设置:

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

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



我真的不知道发生了什么,但这是非常令人沮丧的!任何帮助将是非常感谢!

解决方案

您正在进入物品容器回收。请参阅 http:// blogs。 msdn.com/b/vinsibal/archive/2008/05/14/recycling-that-item-container.aspx 。 WPF正在滚动时重新使用行对象,并且您看到已检查和未检查事件在绑定到另一行时触发。



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



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


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;

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

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!

解决方案

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.

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".

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天全站免登陆