2

誰かがここで私を助けてくれることを本当に願っています。私のプログラムには、チェックボックス列を持つ DataGrid があります。DataGrid の ItemsSource は、プログラムで読み込まれた DataSet です。DataGrid でいくつかの項目を選択してスクロールすると、非常に奇妙な動作が発生します。たとえば、CheckBox を 2 つチェックすると、「2 つが選択されています」と表示されますが、DataGrid を上下にスクロールすると、数字が変わります。スクロールして最初の位置に戻ると、「2が選択されました」に戻ります。奇妙に聞こえるかもしれませんが、ボックスをスクロールすると Checked/Unchecked イベントが呼び出されているようです...非常に奇妙です...

コードの先頭で次のように定義しています。

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;

次の XAML を使用して、"Checked" という名前の DataColumn に 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>

次に、チェックボックスの1つをチェック/チェック解除することで呼び出される次のイベントがあります。

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

そのコードを使用すると、チェックされたアイテムの数は同じままですが、実際のチェックはスクロール中に別のアイテムに移動します。

正直なところ、何が起こっているのかわかりませんが、とてもイライラします!どんな助けでも大歓迎です!

4

1 に答える 1

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イベントを 処理してみてください。

于 2010-08-16T22:17:26.480 に答える