2010-08-16 129 views
2

我真的希望有人能幫助我。我的程序中有一個DataGrid,它有一個複選框列。 DataGrid的ItemsSource是以編程方式加載的DataSet。當我在DataGrid中選擇幾個項目然後滾動它時,出現一些非常奇怪的行爲。例如,當我檢查兩個複選框時,它會告訴我我有「2選中」,但如果我在DataGrid中向上或向下滾動,數字會發生變化。如果我滾動回到初始位置,它會回到「2選擇」。儘管聽起來很奇怪,好像它調用了選中/未選中的事件,當我滾動中...很奇怪...WPF Toolkit DataGrid複選框問題

我有以下的在我的代碼頂部定義:

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

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

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

我必須綁定到命名的DataColumn「選中」使用下面的XAML的財產器isChecked:

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

然後,我有一個被選中/取消選中的複選框的一個叫下列事件:

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代碼綁定,並試圖以編程方式使用以下檢查/取消選中事件來設置:

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

當我使用該代碼,檢查項目的數量保持不變,但實際當我滾動時,檢查移動到不同的項目。

我真的不知道發生了什麼事情,但它非常令人沮喪!任何幫助將不勝感激!

回答

7

您正在運行物料容器回收。見http://blogs.msdn.com/b/vinsibal/archive/2008/05/14/recycling-that-item-container.aspx。在滾動時,WPF會重新使用行對象,並且您會看到Checked和Unchecked事件觸發,因爲它綁定到不同的行。

如果您想堅持使用您當前的解決方案,您可以通過將VirtualizingStackPanel.VirtualizationMode="Standard"添加到您的dtgrd:DataGrid元素來禁用物品容器回收 。您也可以通過添加VirtualizingStackPanel.IsVirtualizing="False"來完全禁用虛擬化。

更好的設計可能是從底層數據模型中獲取數據,而不是依賴於UI事件。嘗試處理DataTable上的DataTable.ColumnChanged事件。

+0

至於處理DataTable.ColumnChanged事件,我不確定你的意思,但第一個soution完美工作!非常感謝你! – 2010-08-17 13:10:18