是什么原因导致我的WPF组合框项目在更改项目资源时需要这么长时间才能刷新?

是什么原因导致我的WPF组合框项目在更改项目资源时需要这么长时间才能刷新?,wpf,data-binding,mvvm,combobox,itemssource,Wpf,Data Binding,Mvvm,Combobox,Itemssource,我有一个datagrid(称之为dat1),它有一个绑定到自定义类型的可观察集合的items源,称之为TypeA。TypeA上的属性之一是另一个自定义类型的可观察集合,称之为TypeB。然后我有一个组合框,其中一个items源绑定到dat1的SelectedItem.TypeB 因此,当用户在dat1中选择TypeA时,组合框将显示所选TypeA中TypeB可观察集合中的项目。有道理吗 绑定可以工作,并且可以更新。问题在于,当组合框中的项目演示者已经显示了项目,并且用户在dat1中选择了不同的T

我有一个datagrid(称之为dat1),它有一个绑定到自定义类型的可观察集合的items源,称之为TypeA。TypeA上的属性之一是另一个自定义类型的可观察集合,称之为TypeB。然后我有一个组合框,其中一个items源绑定到dat1的SelectedItem.TypeB

因此,当用户在dat1中选择TypeA时,组合框将显示所选TypeA中TypeB可观察集合中的项目。有道理吗

绑定可以工作,并且可以更新。问题在于,当组合框中的项目演示者已经显示了项目,并且用户在dat1中选择了不同的TypeA并尝试查看组合框中的新项目时,项目演示者生成新项目时会出现长时间的暂停

为了测试这个问题,我可以简化这个场景

复制步骤:

  • 使用.NET4.0创建新的WPF项目

  • 剪切并粘贴下面的代码

  • 要获得冻结行为,必须删除组合框以查看项目,然后单击按钮以更改项目源,然后再次删除组合框。组合框在几秒钟后下降,但为什么这么慢

  • XAML

    
    
    代码

    公共部分类主窗口:窗口
    {
    公共主窗口()
    {
    初始化组件();
    this.cbo.ItemsSource=junk1;
    }
    ObservableCollection junk1=新的ObservableCollection(){
    新垃圾({Junk1=“Junk1-1”},
    新垃圾({Junk1=“Junk1-2”});
    ObservableCollection junk2=新的ObservableCollection(){
    新垃圾({Junk1=“junk2-1”},
    新垃圾({Junk1=“junk2-2”},
    新垃圾({Junk1=“junk2-3”},
    新垃圾({Junk1=“junk2-4”});
    私有无效btn_单击(对象发送方,路由目标)
    {
    如果(this.cbo.ItemsSource==junk1)
    this.cbo.ItemsSource=junk2;
    其他的
    this.cbo.ItemsSource=junk1;
    }
    }
    公共类垃圾
    {
    公共字符串Junk1{get;set;}
    }
    
    注意:这是一个WPF问题。我听说Silverlight没有同样的问题。我不需要知道Silverlight是否有效。我需要一个WPF答案

    PS.当项目源更改为junk2时,延迟更长,可能是因为它更大


    它延迟的时间足够长,我认为这可能是由绑定异常引起的,因为异常需要时间。有没有办法查看是否抛出了绑定异常?

    我也观察到了这种现象。 我正在Windows7x64上使用VisualStudio2010(带ReSharper 6.0)

    在上面的例子中,只有四个项目是不明显的,但是如果我做了,例如50个或更多的项目,冻结会变得非常明显。 在重新绑定之后,它将挂起大约15秒,然后我才能再次与它交互

    另一件有趣的事情是,只有在VS中调试时才会发生这种情况。如果我独立运行exe,它会非常快速

    以下是我的简单项目中的代码:

    XAML

    
    
    代码

    使用System.Collections.ObjectModel;
    使用System.Windows;
    名称空间组合框冻结
    {
    公共部分类主窗口
    {
    公共主窗口()
    {
    初始化组件();
    加载+=主窗口\u加载;
    _junk1=新的可观测集合();
    对于(int i=0;i<50;i++)
    {
    _添加(新垃圾{junk1=“Prop1a-”+i,Junk2=“Prop1b-”+i});
    }
    _junk2=新的可观测集合();
    对于(int i=0;i<50;i++)
    {
    _添加(新垃圾{Junk1=“Prop2a-”+i,junk2=“Prop2b-”+i});
    }
    }
    私有只读可观察收集_junk1;
    私有只读可观察收集_junk2;
    已加载无效主窗口(对象发送器、路由目标)
    {
    cbo.ItemsSource=_junk1;
    }
    私有无效btn_单击(对象发送方,路由目标)
    {
    如果(cbo.ItemsSource==\u junk1)
    {
    cbo.ItemsSource=_junk2;
    }
    其他的
    {
    cbo.ItemsSource=_junk1;
    }
    }
    }
    公共类垃圾
    {
    公共字符串Junk1{get;set;}
    公共字符串Junk2{get;set;}
    }
    }
    

    如果找到解决方案或解决方法,我将再次在此发布。

    调试时,您应该会在VS IDE的输出窗口中看到绑定异常。我看不到您发布的代码有任何长时间的暂停。同样,在这里,似乎没有任何犹豫。在我的笔记本电脑上运行VS2008,Win7 x64,Resharper 5.1,此代码非常快速。这里没有犹豫的问题。我想知道在您的机器上运行此程序时是否值得发布完整的调试输出。也许检查正在加载的程序集版本可以提供一些见解。
    <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>
    
    <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>