开发者

Binding converted Enum to a ComboBox

开发者 https://www.devze.com 2023-02-22 11:01 出处:网络
I tried to bind the following Enum to a ComboBox Public Enum PossibleActions ActionRead ActionWrite ActionVerify

I tried to bind the following Enum to a ComboBox

Public Enum PossibleActions
  ActionRead
  ActionWrite
  ActionVerify
End Enum

I can't change the Enum itself, but I do not want to display these strings. My intention is just to cut the prefix 'Action' and display 'Read', 'Write' and 'Verify' in the ComboBox. Therefore I wrote a ValueConverter

Public Class PossibleActionsConverter
  Implements IValueConverter

      Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
        Dim actions() As PossibleActions
        Dim strings() As String

        actions = CType(value, PossibleActions())
        ReDim strings(actions.GetUpperBound(0))
        For i = 0 To actions.GetUpperBound(0)
          strings(i) = actions(i).ToString.Substring(6)
        Next
        Return strings
      End Function

      Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Dim s As String

        s = CStr(value)

        Return [Enum].Parse(GetType(PossibleActions), "Action" & s)
      End Function
    End Class

My XAML looks like

xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:StepEditor"

[...]

<Window.Resources>
    <ObjectDataProvider x:Key="possibleActionsEnum" MethodName="GetValues"
                        ObjectType="{x:Type sys:Enum}">
        <O开发者_Python百科bjectDataProvider.MethodParameters>
            <x:TypeExtension Type="local:PossibleActions"></x:TypeExtension>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
    <local:PossibleActionsConverter x:Key="possibleActionsConverter"></local:PossibleActionsConverter>
</Window.Resources>

[...]

Either:

<ComboBox ItemsSource="{Binding Source={StaticResource possibleActionsEnum}, Converter={StaticResource possibleActionsConverter}}"
          SelectedItem="{Binding SelectedAction}"></ComboBox>

Or:

<ComboBox ItemsSource="{Binding Source={StaticResource possibleActionsEnum}, Converter={StaticResource possibleActionsConverter}}"
          SelectedItem="{Binding SelectedAction, Converter={StaticResource possibleActionsConverter}}"></ComboBox>

My problem is the binding of the selected item. It fails, but I can't figure out why.


The binding of SelectedItem is wrong, because you convert your Enum into Strings, but SelectedItems is a single string. If you want to stick on this architecture, write a converter that converts a single string back to your enum. The Convert and ConvertBack-methods of your existing converter are close to the solution. They can look like:

  Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
    Dim action As PossibleActions

    action = CType(value, PossibleActions)
    Return action.ToString.Substring(6)
  End Function

  Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
    Dim s As String

    s = CStr(value)
    Return [Enum].Parse(GetType(PossibleActions), "Action" & s)
  End Function


The best solution here iMHO is to use a data template, so you don't have to implement 2 converters as in the previous answer (one that converts a single enum, and another that converts an array). Using a datatemplete, the converter can be applied to each item of the drop down individually, so the converter that converts an array is no longer needed.

 <ComboBox.ItemTemplate>
   <DataTemplate>
     <TextBlock Text="{Binding Converter={StaticResource possibleActionConverter}}" />
   </DataTemplate>
 </ComboBox.ItemTemplate>

with possibleActionConverter converting a single enum to string.

HTH

0

精彩评论

暂无评论...
验证码 换一张
取 消