繁体   English   中英

ComboBox上的SelectedItem绑定未显示所选值

[英]SelectedItem binding on ComboBox not showing selected value

我正在尝试构建一个设置页面,以允许用户选择要在项目滑动(例如Outlook应用)上执行的操作。

为此,我创建了一个包含可用操作的enum ,并将其绑定到ComboBox

一切正常,用户可以选择操作,并且其选择已正确保存。 问题在于,当我导航到页面时, ComboBox不会显示所选的项目,它仅在选择后显示。

这意味着,如果用户更改选择,则ComboBox会更新,但是所选项目在导航时显示为空白。

这是我的代码:

(XAML)

<ComboBox x:Uid="LeftActionComboBox"
          Grid.Row="0"                          
          HorizontalAlignment="Stretch"                          
          SelectedItem="{Binding LeftSwipeActionType, Mode=TwoWay, Converter={StaticResource StringToSwipeActionTypesConverter}}"
          ItemsSource="{Binding LeftSwipeActionType, Converter={StaticResource EnumToStringListConverter}}"/>

(VM属性)

public SwipeActionTypes LeftSwipeActionType
{
    get { return _settings.LeftSwipeActionTypeProperty; }
    set
    {
        _settings.LeftSwipeActionTypeProperty = value;
        // RaisePropertyChanged causes a StackOverflow, but not using it is not the problem since the ComboBox is empty only before set
    }
}

(转换器StringToSwipeActionTypesConverter ,已准备好本地化)

// Returns localized string value for the Enum
public object Convert(object value, Type targetType, object parameter, string language)
{
    var enumValue = (SwipeActionTypes) value;
    switch (enumValue)
    {
        case SwipeActionTypes.Copy:
            return App.ResourceLoader.GetString("CopySwipeActionName");
        case SwipeActionTypes.Delete:
            return App.ResourceLoader.GetString("DeleteSwipeActionName");
        default:
            throw new ArgumentOutOfRangeException();
    }
}

// Parses the localized string into the enum value
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
    var stringValue = (string) value;
    if (stringValue.Equals(App.ResourceLoader.GetString("CopySwipeActionName")))
    {
        return SwipeActionTypes.Copy;
    }
    if (stringValue.Equals(App.ResourceLoader.GetString("DeleteSwipeActionName")))
    {
        return SwipeActionTypes.Delete;
    }
    return null;
}

(转换器EnumToStringListConverter

public object Convert(object value, Type targetType, object parameter, string language)
{
    var valueType = value.GetType();
    return Enum.GetNames(valueType).ToList();
}

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

知道为什么失败了吗?

首先,这是您的方法有什么问题:您正在将ItemsSource绑定到与SelectedItem相同的属性,即使使用转换器很难,这可能会导致无限的更新周期-并且您不希望这样做。

一遍又一遍地生成相同的静态元素列表似乎有些浪费。 与其传递类型的实例,不如传递类型本身到转换器:

EnumToMembersConverter.cs

public class EnumToMembersConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return Enum.GetValues((Type)value).ToList();
    }

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

XAML

ItemsSource="{Binding Source={x:Type whateverNamespace:SwipeActionTypes}, Converter={StaticResource EnumToMembersConverter}}"

这将为您提供SwipeActionTypes所有 ,因此您可以直接绑定它,而无需再次转换。

SelectedItem="{Binding LeftSwipeActionType, Mode=TwoWay}"

对于字符串以外的类型,使用ComboBox并没有错,因此,请使其成为进一步操作的基础:

<ComboBox x:Uid="LeftActionComboBox"
      Grid.Row="0"                          
      HorizontalAlignment="Stretch"                          
      SelectedItem="{Binding LeftSwipeActionType, Mode=TwoWay}"
      ItemsSource="{Binding Source={x:Type whateverNamespace:SwipeActionTypes}, Converter={StaticResource EnumToMembersConverter}}"/>

您写所有这些转换的原因可能是因为ComboBox显示了奇怪的值而不是可读的字符串。 不用担心,我们已经有了您的转换器,您只需要对其进行转换 (将SwipeActionTypes转换为String )并将其应用于TextBox即可:

<ComboBox x:Uid="LeftActionComboBox"
      Grid.Row="0"                          
      HorizontalAlignment="Stretch"                          
      SelectedItem="{Binding LeftSwipeActionType, Mode=TwoWay}"
      ItemsSource="{Binding Source={x:Type whateverNamespace:SwipeActionTypes}, Converter={StaticResource EnumToMembersConverter}}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=., Converter = {StaticResource SwipeActionTypesStringConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

注意,我没有运行此代码,因此您可能需要相应地调整使用的名称空间

出现StackOverflow异常的原因是,每次更改LeftSwipeActionType属性时,您都在更改ComboBox的ItemsSource,它更改了SelectedItem,从而触发了INotifyPropertyChanged,从而更改了ItemsSource,依此类推。

一旦停止对ItemsSource和SelectedItem使用相同的属性,则将设置正确的初始选择。

而不是使用转换器来创建ItemsSource,而应该在ViewModel中创建

public MyViewModel(type enumType)
{
    SourceForItems = Enum.GetValues(enumType);
}

public IEnumerable SourceForItems { get; private set; }

暂无
暂无

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

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