0

私は2つのコンボボックスを持っています。両方の項目は列挙値です。コンボFooでの選択に応じて、コンボバーで使用できるさまざまな項目があります(バインディングの変更)。初めての場合は、 comboFooが以前にポップアップしたかどうに関係なく、常にすぐにポップアップします。しかし、comboFoo で選択を変更するたびに( comboBarが少なくとも 1 回ポップアップした後) 、 comboBar のポップアップは非常に遅くなります。私はそれを修正する方法がわかりません。

列挙型

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

列挙型のマークアップ

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

コンバーター(使用法は以下の方法を参照)

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 メソッド(分離コード)

    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

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

コンボバーの代わりにリストボックスを使用する場合、パフォーマンスの問題はないので、問題はコンバーターに属していないと思います...

PS: VS2010、.NET4.0、Debug-Build および Release-Build テスト済み

4

1 に答える 1

0

OK、バインディングの問題は、.NET4 を使用する Windows Vista でのみ発生するようです。おそらく、コンボボックス自体のバグです。上記のコードは問題ありません。

私はそれをテストしました:

  • win8、.net 4.5、vs2012: 問題なし
  • win8、.net 4.0、vs2012: 問題なし
  • win7、.net 4.0、vs2010: 問題ありません (同僚のコンピューターで)
  • vista、.net 4.0、vs2010:問題(別の同僚のコンピューターと私のコンピューター)
于 2013-08-19T08:03:51.607 に答える