ComboBox最初不会选择绑定值

时间:2016-02-24 10:27:35

标签: c# xaml combobox uwp win-universal-app

首先,不是重复。

TextBox和CheckBox正常工作,而不是ComboBox。

模型

internal class Word : _Model
{
    public enum Categories
    {
        Noun,
        Verb,
    }

    private Categories category;
    public Categories Category
    {
        get
        {
            return this.category;
        }
        set
        {
            this.SetProperty(ref this.category,
                             value);
        }
    }
}

通知(安全跳过阅读本部分)

internal abstract class _Model : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(storage, value))
        {
            return false;
        }
        storage = value;
        this.OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var eventHandler = this.PropertyChanged;
        if (eventHandler != null)
        {
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

控制(模型)

public sealed partial class WordEditor : UserControl
{
    public WordEditor()
    {
        this.Model = new Models.Word();
        this.Model.Category = Models.Word.Categories.Verb;
        this.InitializeComponent();
    }

    private Models.Word Model { get; set; }

    internal IList<KeyValuePair<Models.Word.Categories, string>> Categories { get { return new List<KeyValuePair<Models.Word.Categories, string>>() { new KeyValuePair<Models.Word.Categories, string>(Models.Word.Categories.Noun, "Noun"), new KeyValuePair<Models.Word.Categories, string>(Models.Word.Categories.Verb, "Verb") }; } }
}

装订

<UserControl.Resources>
    <converters:AnyConverter x:Key="AnyConverter"/>
</UserControl.Resources>

<StackPanel>
    <ComboBox ItemsSource="{x:Bind Path=Categories, Mode=OneTime}"
              DisplayMemberPath="Value"
              SelectedValuePath="Key"
              SelectedValue="{x:Bind Path=Model.Category, Mode=TwoWay, Converter={StaticResource ResourceKey=AnyConverter}}"/>
</StackPanel>

转换器

internal class AnyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value;
    }
}

问题

ComboBox正确显示“动词”和“名词”,模型正确反映“动词”或“名词”的选择。

但是,即使在第一个位置将类别设置为Verb,ComboBox也不显示。

如何修复它以便ComboBox在第一次出现时选择“动词”?

2 个答案:

答案 0 :(得分:3)

我转载了你的问题。这里的问题是ComboBox.SelectedValue不适用于枚举类型。要对此进行测试,我们可以使用ComboBox而无需绑定,并将SelectedValue设置为代码隐藏,如:

<ComboBox x:Name="cmb" DisplayMemberPath="Value" SelectedValuePath="Key" />

cmb.ItemsSource = Categories;
cmb.SelectedValue = Models.Word.Categories.Verb;

虽然我已将Models.Word.Categories.Verb设置为SelectedValue,但其值仍为nullenter image description here

但是,当Value类型为intstring时,它有效。从我的WPF经验来看,枚举类型也应该有效。我认为这可能是UWP中的一个错误。

作为一种解决方法,我认为您可以使用SelectedIndexSelectedItem属性在ComboBox首次出现时选择“Verb”。例如:

在XAML中,使用SelectedIndex代替SelectedValue

<ComboBox DisplayMemberPath="Value"
          ItemsSource="{x:Bind Path=Categories, Mode=OneTime}"
          SelectedIndex="{x:Bind Path=Model.Category, Mode=TwoWay, Converter={StaticResource ResourceKey=AnyConverter}}"
          SelectedValuePath="Key" />

并更改Converter之类的内容:

internal class AnyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (int)(Models.Word.Categories)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return (Models.Word.Categories)(int)value;
    }
}

在此之后,设置this.Model.Category = Models.Word.Categories.Verb;将有效。

答案 1 :(得分:0)

起初我认为@Jay Zuo - MSFT是正确的,因为你必须将它转换成另一种形式(例如int);但是,通过使用SelectedItem,它可以工作!我使用SelectedValue喜欢OP,但没有定义SelectedValuePath,也不会选择初始值。绑定到SelectedItem甚至没有定义SelectedValuePath

注意,如果绑定到SelectedItemSelectedIndex,则无需转换器。

我使用Windows 10 Anniversary Edition(10.0; Build 14393)进行了测试。

<强>更新

原来我错了;为了更方便,我最终推出了自己的转换器。

public abstract class EnumToIntConverter<TEnum> : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is Enum)
            return (int)value;

        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        if (value is int)
            return (TEnum)value;

        return DependencyProperty.UnsetValue;
    }
}

public sealed class MyEnumToIntConverter : EnumToIntConverter<MyEnum>
{
    //Do nothing!
}

澄清一下,SelectedIndex 绝对需要