简体   繁体   English

wpf combobox-更改绑定后的性能

[英]wpf combobox - performance after changing binding

I have two comboboxes. 我有两个组合框。 The items of both are enum values. 两者的项目都是枚举值。 Depending on selection in combo Foo there are different items available in combo Bar (binding change). 根据组合 Foo中的选择, 组合 栏中可以使用不同的项目(装订更改)。 The first time comboBar always pops up quickly - no matter wether comboFoo has popped up before or not. 第一次comboBar总是快速弹出-无论comboFoo是否之前弹出。 But after every selection change in comboFoo (after comboBar has popped up at least one time) comboBar pops up very slowly. 但是,在comboFoo中的每个选择更改之后 (在comboBar弹出至少一次之后), comboBar弹出非常缓慢。 I have not any idea how to fix it. 我不知道如何解决它。

Enums 枚举

public enum Foo
{
    Foo1, Foo2, Foo3
}

public enum Bar
{
    Bar1, Bar2, Bar3, Bar4, Bar5, Bar6, Bar7, Bar8, Bar9, Bar10, 
    Bar11, Bar12, Bar13, Bar14, Bar15, Bar16, Bar17, Bar18,
}

Mark up for enums 标记为枚举

public class EnumValuesExtension : MarkupExtension
{
    private readonly Type enumType;

    public EnumValuesExtension(Type enumType)
    {
        if (enumType == null)
            throw new ArgumentNullException("enumType");

        if (!enumType.IsEnum)
            throw new ArgumentException("Argument enumType must derive from type Enum.");

        this.enumType = enumType;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return Enum.GetValues(enumType);
    }
}

Converter (usage see method below) 转换器 (用法请参见下面的方法)

public class EnumToFilteredListConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (!(value is Type))
            return null;

        var enumType = (Type)value;

        if (!enumType.IsSubclassOf(typeof(Enum)))
            return null;

        Array allValues = Enum.GetValues(enumType);

        IEnumerable enumList;
        var filterList = (parameter == null) ? Enum.GetValues(enumType).Cast<Enum>() : (parameter as Array).Cast<Enum>();

        try
        {
            enumList = from Enum enumValue in allValues
                       where filterList.Contains(enumValue)
                       select enumValue;
        }
        catch (ArgumentNullException)
        {
            enumList = allValues;
        }
        catch (ArgumentException)
        {
            enumList = allValues;
        }
        return enumList;

    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

SelectionChanged method (code behind) SelectionChanged方法 (后面的代码)

    private void cboFoo_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (comboBar == null)
            return;

        if (comboFoo.SelectedItem == null)
            return;

        var binding = new Binding
                          {
                              Source = typeof(Bar),
                              Converter = new EnumToFilteredListConverter()
                          };

        switch ((Foo)comboFoo.SelectedItem)
        {
            case Foo.Foo1: // Show only Bar1-Bar3
                binding.ConverterParameter = new Enum[] { Bar.Bar1, Bar.Bar2, Bar.Bar3 };
                break;
            case Foo.Foo2: // Show only Bar3-Bar5
                binding.ConverterParameter = new Enum[] { Bar.Bar3, Bar.Bar4, Bar.Bar5 };
                break;
            default: // Show all of Bar
                binding.ConverterParameter = null;
                break;
        }

        comboBar.SetBinding(ItemsControl.ItemsSourceProperty, binding);
    }

XAML XAML

<StackPanel>            
    <ComboBox Name="comboFoo" ItemsSource="{Binding Source={markup:EnumValues {x:Type types:Foo}}}" SelectionChanged="cboFoo_SelectionChanged" />
    <ComboBox Name="comboBar" ItemsSource="{Binding Source={markup:EnumValues {x:Type types:Bar}}}" />
    <!--<ListBox Name="comboBar" ItemsSource="{Binding Source={markup:EnumValues {x:Type types:Bar}}}" />-->
</StackPanel>

If I use a listbox instead of comboBar I have not any performance problem, so I think the problem does not belong to the converter... 如果我使用列表框而不是comboBar ,那么我没有任何性能问题,因此我认为问题不属于转换器...

PS: VS2010, .NET4.0, Debug-Build and also Release-Build tested PS:VS2010,.NET4.0,调试版本以及发布版本均经过测试

Ok, the binding problem seems to be only on Windows Vista with .NET4 - probably a bug in combobox itself. 好的,绑定问题似乎仅在具有.NET4的Windows Vista上-可能是combobox本身的错误。 The code above is fine. 上面的代码很好。

I tested it with: 我用以下方法进行了测试:

  • win8, .net 4.5, vs2012: no problem win8,.net 4.5和vs2012:没问题
  • win8, .net 4.0, vs2012: no problem win8,.net 4.0和vs2012:没问题
  • win7, .net 4.0, vs2010: no problem (on my colleague's computer) win7,.net 4.0和vs2010:没问题(在我同事的计算机上)
  • vista, .net 4.0, vs2010: problem (on another colleague's computer and on my one) Vista,.net 4.0,vs2010: 问题 (在另一位同事的计算机和我的计算机上)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM