2010-12-10 1 views
0

관찰 할 수있는 사용자 지정 형식 컬렉션에 바인딩 된 항목 원본을 가진 datagrid (dat1이라고 함)가 있는데이를 TypeA라고합니다. TypeA의 속성 중 하나는 다른 사용자 정의 유형의 관찰 가능한 컬렉션이며 TypeB라고합니다. 그런 다음 dat1의 SelectedItem.TypeB에 바인딩 된 항목 소스가있는 콤보 상자가 있습니다.항목 소스가 변경 될 때 WPF 콤보 상자 항목을 새로 고치는 데 너무 오래 걸리는 원인이 무엇입니까?

그래서 사용자가 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 응답이 필요합니다.

추신. 항목 원본이 junk2로 변경되면 지연 시간이 길어집니다. 이는 아마도 원본 크기가 크기 때문일 수 있습니다.

지연 시간이 너무 오래 걸리기 때문에 예외가 바인딩 된 것으로 생각됩니다. 바인딩 예외가 발생하는지 확인하는 방법이 있습니까?

+0

디버깅하는 동안 VS IDE의 출력 창에 바인딩 예외가 표시되어야합니다. – VoodooChild

+0

게시 한 코드에 오래 걸리지 않습니다. – lesscode

+0

마찬가지로 여기에서도 주저하지 않습니다. –

답변

0

이 현상 역시 관찰됩니다. Windows 7 x64에서 Visual Studio 2010 (ReSharper 6.0 포함)을 사용하고 있습니다.

위의 예와 같이 네 가지 항목만으로 눈에 띄지는 않지만, 예를 들면. 50 개 이상의 항목은 동결이 매우 눈에 띄게됩니다. 다시 바인딩하면 15 초 정도 걸리므로 다시 상호 작용할 수 있습니다.

또 다른 흥미로운 점은 VS에서 디버깅하는 동안에 만 발생한다는 것입니다. exe를 독립 실행 형이라면 정말 빠르고 부드럽습니다.

XAML 나는이에 대한 해결책이나 해결 방법을 찾으면 내가 다시 여기에 게시 할 예정입니다

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

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

코드 : 여기

내 간단한 프로젝트에서 코드입니다.

+0

내 랩톱에서 VS2008, Win7 x64, Resharper 5.1에서 실행 중입니다.이 코드는 매우 이상합니다. 주저하지 마라. 내 컴퓨터에서 이걸 실행할 때 전체 디버그 출력을 게시하는 것이 가치가 있는지 궁금합니다. 아마도로드되는 어셈블리 버전을 검사하는 것은 약간의 통찰력을 제공 할 수 있습니다. – RMart

관련 문제