web-dev-qa-db-ja.com

ItemsControlがその項目ソースと矛盾しています-WPFリストボックス

ボタンクリックメソッドが実行されたときに入力されるListBoxコントロールを含むWPFウィンドウがあります。

XAML:

<ListBox Name="ThirdPartyListBox" ItemsSource="{Binding}" Margin="0,70,0,0">                      
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Image Source="C:\Users\Test\Desktop\Project\ACME-WPF\ACME-WPF\window-new-3.ico" Margin="5" Width="50"/>
                                <Button Name="ThirdPartyInstallButton" Content="Install" Click="InstallThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
                                <Button Name="ThirdPartyPostoneButton" Content="Postpone" Click ="PostponeThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
                                <TextBlock FontWeight="Bold" Text="{Binding Item2.Name}" Margin="12,25,0,0"/>
                                <TextBlock FontWeight="Bold" Text="{Binding Item2.RequiredVersion}" Margin="3,25,0,0"/>
                                <TextBlock Text="{Binding Item2.CustomUIMessage}" Margin="10,25,0,0" TextWrapping="Wrap" Foreground="Red"/>
                                <TextBlock Text="You have used " Margin="3,25,0,0"/>
                                <TextBlock Text="{Binding Item3.UsedDeferrals}" Margin="3,25,0,0"/>
                                <TextBlock Text=" of " Margin="3,25,0,0"/>
                                <TextBlock Text="{Binding Item2.MaxDefferals}" Margin="3,25,0,0"/>
                                <TextBlock Text=" deferrals for this update." Margin="3,25,0,0"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

C#:

 private void CheckforThirdPartyUpdatesButton_Click(object sender, RoutedEventArgs e)
    {
        CheckforThirdPartyUpdatesButton.IsEnabled = false;

        worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            MainEntry.checkFor3PUpdates();
        };

        worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
        {

        };

        worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
        {

            ThirdPartyListBox.DataContext = RegScan_ThirdParty.comparisonListWithState;
            CheckforThirdPartyUpdatesButton.IsEnabled = true;
        };

        worker.RunWorkerAsync();
    }

この時点までのすべてが期待どおりに機能し、リストにあるアイテムの数に応じて、リストボックスに複数のアイテム行が表示されますThirdPartyListBox.DataContext = RegScan_ThirdParty.comparisonListWithState;。ただし、リストボックスのアイテムを操作すると、InvalidOperationExceptionがスローされ、「ItemsControlがそのアイテムソースと矛盾しています」という内部例外が発生します。

誰かが私に何が起こっているのかを理解するのを手伝ってくれる?

19
user3342256

このような例外は、アイテムのソースが別のスレッドから変更され、ListBoxCollectionChangedの変更に関する通知(ItemsSourceイベント)を受信しない場合にスローされます。したがって、レイアウトの更新などの作業を開始すると、ItemsItemsSourceと等しくないことがわかり、例外がスローされます。

.NET 4.5以降、WPFは、異なるスレッドから変更されたコレクションとの同期を可能にする方法を提供します。 EnableCollectionSynchronizationItemsSource メソッドを使用してみてください。 同様の質問に対するこの回答の使用例を参照してください

24
neptunao

バインディングリソースが変更されたコントロールでRefresh()メソッドを呼び出すだけです。

myListBox.Items.Refresh();
20
Dragon

単一のメソッドでUIバインディングを使用してリストを複数回(ループ)クリアして更新していたため、まったく同じエラーメッセージに遭遇しました。

解決策は、一時的なリストを作成し、新しいリストを一度だけ割り当てることでした。

直接あなたの問題ではなく同じエラーなので、私はここでそれを言及しようと思いました...

1
CodingYourLife