カスタムタイプの監視可能なコレクションにバインドされた項目ソースを持つデータグリッド (dat1 と呼びます) があり、それを TypeA と呼びます。TypeA のプロパティの 1 つは、TypeB と呼ばれる別のカスタム型の監視可能なコレクションです。次に、アイテム ソースが dat1 の SelectedItem.TypeB にバインドされたコンボ ボックスを作成します。
そのため、ユーザーが dat1 で TypeA を選択すると、コンボボックスには、選択した TypeA の TypeB オブザーバブル コレクションのアイテムが表示されます。わかる?
バインディングは機能し、更新されます。問題は、コンボボックスのアイテム プレゼンターが既にアイテムを表示しているときに、ユーザーが dat1 で別の TypeA を選択し、コンボボックスで新しいアイテムを表示しようとすると、アイテム プレゼンターが新しいアイテムを生成する間、長い一時停止が発生することです。
問題をテストするために、シナリオを単純化できます。
再現する手順:
.NET 4.0 を使用して新しい WPF プロジェクトを作成します。
以下のコードをカット&ペーストしてください。
フリーズ動作を取得するには、コンボボックスをドロップしてアイテムを表示し、ボタンをクリックしてアイテムのソースを変更し、コンボボックスを再度ドロップする必要があります。コンボボックスは数秒後にドロップしますが、なぜそんなに遅いのでしょうか?
XAML
<Window x:Class="ComboBoxTest.MainWindow"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<ComboBox x:Name="cbo" DisplayMemberPath="Junk1"></ComboBox>
<Button Content="Click Me!" Click="btn_Click"></Button>
</StackPanel>
</Grid>
</Window>
コード
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.cbo.ItemsSource = junk1;
}
ObservableCollection<Junk> junk1 = new ObservableCollection<Junk>() {
new Junk() { Junk1 = "junk1 - 1" },
new Junk() { Junk1 = "junk1 - 2" } };
ObservableCollection<Junk> junk2 = new ObservableCollection<Junk>() {
new Junk() { Junk1 = "junk2 - 1" },
new Junk() { Junk1 = "junk2 - 2" },
new Junk() { Junk1 = "junk2 - 3" },
new Junk() { Junk1 = "junk2 - 4" } };
private void btn_Click(object sender, RoutedEventArgs e)
{
if (this.cbo.ItemsSource == junk1)
this.cbo.ItemsSource = junk2;
else
this.cbo.ItemsSource = junk1;
}
}
public class Junk
{
public string Junk1 { get; set; }
}
注: これは WPF の問題です。Silverlight には同じ問題がないと聞いたことがあります。Silverlight が機能するかどうかを知る必要はありません。WPFの回答が必要です。
PS。アイテムのソースが jump2 に変更されると、遅延が長くなります。これは、おそらくサイズが大きいためです。
例外には時間がかかるため、バインド例外が原因であると思われるほど十分に遅延します。バインディング例外がスローされているかどうかを確認する方法はありますか?