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