2010-12-10 57 views
0

我有一個數據網格(稱爲dat1),它有一個項目源綁定到一個自定義類型的可觀察集合,稱之爲TypeA。 TypeA上的其中一個屬性是另一個自定義類型的可觀察集合,稱爲TypeB。然後我有一個組合框,綁定到dat1的SelectedItem.TypeB。什麼是導致我的WPF組合框項目花費這麼長時間來刷新itemssource時更改?

因此,當用戶在dat1中選擇TypeA時,組合框將顯示來自所選TypeA的TypeB可觀察集合中的項目。合理?

該綁定能工作,它會更新。問題是,當組合框中的項目演示者已經顯示項目並且用戶在dat1中選擇了不同的TypeA並嘗試查看組合框中的新項目時,項目演示者生成新項目時會有很長的暫停。

爲了測試這個問題,我可以簡化這個場景。

重現步驟:

  1. 創建使用.NET 4.0一個新的WPF項目。

  2. 剪下並粘貼下面的代碼。

  3. 要獲得凍結行爲,必須放下組合框以查看項目,然後單擊該按鈕,以便項目源更改,然後再次放下組合框。幾秒鐘後組合框下降,但爲什麼這麼慢?

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。當項目源更改爲junk2時,延遲時間會更長,可能是因爲它較大。

它足夠延遲,我認爲它可能是由綁定異常引起的,因爲異常需要時間。有沒有辦法查看是否存在綁定異常?

+0

你應該看到在VS IDE輸出窗口綁定例外,而調試。 – VoodooChild 2010-12-10 02:13:10

+0

我沒有看到您發佈的代碼有太長時間的停頓。 – lesscode 2010-12-10 02:25:16

回答

0

我也觀察過這種現象。 我在Windows 7 x64上使用Visual Studio 2010(使用ReSharper 6.0)。

上面的例子中只有四個項目並不明顯,但如果我讓它例如50個或更多的項目凍結非常明顯。 重新綁定後,它會掛起大約15秒,然後我才能再次與之互動。

另一個有趣的事情是,這隻發生在調試VS.如果我單獨運行exe文件,它真的很快速。

這裏是我的簡單的項目代碼:

XAML

<Window x:Class="ComboBoxFreeze.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
    <ComboBox x:Name="cbo" DisplayMemberPath="Junk1"></ComboBox> 
    <Button Content="Click Me!" Click="btn_Click"></Button> 
    </StackPanel> 
</Window> 

代碼

using System.Collections.ObjectModel; 
using System.Windows; 

namespace ComboBoxFreeze 
{ 
    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      Loaded += MainWindow_Loaded; 

      _junk1 = new ObservableCollection<Junk>(); 
      for (int i = 0; i < 50; i++) 
      { 
       _junk1.Add(new Junk { Junk1 = "Prop1a-" + i, Junk2 = "Prop1b-" + i }); 
      } 


      _junk2 = new ObservableCollection<Junk>(); 
      for (int i = 0; i < 50; i++) 
      { 
       _junk2.Add(new Junk { Junk1 = "Prop2a-" + i, Junk2 = "Prop2b-" + i }); 
      } 
     } 

     private readonly ObservableCollection<Junk> _junk1; 

     private readonly ObservableCollection<Junk> _junk2; 

     void MainWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      cbo.ItemsSource = _junk1; 
     } 

     private void btn_Click(object sender, RoutedEventArgs e) 
     { 
      if (cbo.ItemsSource == _junk1) 
      { 
       cbo.ItemsSource = _junk2; 
      } 
      else 
      { 
       cbo.ItemsSource = _junk1; 
      } 
     } 
    } 

    public class Junk 
    { 
     public string Junk1 { get; set; } 
     public string Junk2 { get; set; } 
    } 
} 

我會再次張貼在這裏,如果我找到一個解決方案或替代方法這一點。

相關問題