`

wpf - specify enum values in xaml

    博客分类:
  • WPF
wpf 
阅读更多

Many a situation you find that you are in wantting to put some enum values into the xaml files, there are basically two ways..  one is the Property element where you can directly create values of the Enum by some type of conversion.

 

<local:MyEnum>Value1</local:MyEnum>

 and another is the use of x:Static construct, where it looks like this:  

<x:Static Member="local:MyEnum.Value2" />

 

at places where the x:StaticExtension is supported, you can try to do this

 

<... Value="{x:Static local:MyEnum.Value1" />

 

Here we will show you the following 

 

  • how to specicy the enum literal in xaml for enum directly in the namespace root
  • how to specify enum literal for enum defined inside some outer classes
  • how to get all values of enums. with help of ObjectDataProvider.

First, let see how normally you can specify the enum literals.

 

            <x:Array Type="{x:Type local:MyEnum}" x:Key="EnumValuesSource">
                <local:MyEnum>Value1</local:MyEnum>
                <x:Static Member="local:MyEnum.Value2" />
                <local:MyEnum>Value3</local:MyEnum>
            </x:Array>

 

and you can make a ObjectDataProvider as such  

 

            <ObjectDataProvider MethodName="GetValues"        
                  ObjectType="{x:Type sys:Enum}"        
                  x:Key="EnumValuesSource3"
                                >
                <ObjectDataProvider.MethodParameters>
                    <x:TypeExtension Type="{x:Type local:MyEnum}" />
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>

 

If only we can do that Property attribute syntax, it will allow us to do the following. 

            <x:Type x:Key="typeToPassIn" TypeName="local:MyEnum" />
            <local:MyEnum x:Key="valueToPassIn">Value1</local:MyEnum>
           <ObjectDataProvider MethodName="GetValues"        
                          ObjectType="{x:Type sys:Enum}"        
                          x:Key="ExampleEnumValues"
                          MethodParameters="{StaticResource valueToPassIn}">
            </ObjectDataProvider>

 however, we have to use the Property element sytax, which looks like above. 

 

 

this is a side note, when you creat a x:Type object, you can use the TypeName or the x:type markup extension, however, according to the test, WPF does not support (maybe the ObjectDataProvider does not support) that type of Type object. 

 

with type property 

<x:Type x:Key="typeToPassIn2" Type="{x:Type local:MyEnum}" />

 with typeName property

<x:Type x:Key="typeToPassIn" TypeName="local:MyEnum" />

 

 

What if the Enum is nested inside another class, who can we use that in Xaml code? You will need to use like this : 

 

            <x:Array Type="{x:Type local:OuterClass+MyEnum}" x:Key="EnumInAnotherClass">
                <x:Static Member="local:OuterClass+MyEnum.Value1" />
                <x:Static Member="local:OuterClass+MyEnum.Value2" />
                <x:Static Member="local:OuterClass+MyEnum.Value2" />
            </x:Array>

 

Notice the '+' sign in the middle of the containing class and the enum inside. 

 

 

Now let's see the code that we have created for an example ..

// MyEnum.cs
namespace enumInXamldemo
{
    public enum MyEnum {
        Value1, Value2, Value3  
    }
}

 and the outerClass.cs

 

// OuterClass.cs
    public class OuterClass
    {
        public enum MyEnum
        {
            Value1, Value2, Value3
        }
    }

 

Last is the MainWindow.xaml file

 

<Window x:Class="enumInXamldemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:enumInXamldemo"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        >
    <Grid>
        <Grid.Resources>
            <x:Array Type="{x:Type local:MyEnum}" x:Key="EnumValuesSource">
                <local:MyEnum>Value1</local:MyEnum>
                <x:Static Member="local:MyEnum.Value2" />
                <local:MyEnum>Value3</local:MyEnum>
                
            </x:Array>



            <!-- 
            Check on the answer from: 
              rudigrobler
            
            http://stackoverflow.com/questions/3751461/wpf-enumeration-value-as-objectdataproviders-method-parameter
            
            -->
            
            <!-- Becareful of the pitfall
            
                the typename is not well supported in all XAML families, it does not work in the EnumValuesSource2 shown below.  
            -->
            <x:Type x:Key="typeToPassIn" TypeName="local:MyEnum" />
            <local:MyEnum x:Key="valueToPassIn">Value1</local:MyEnum>

          <!-- this won't work because 
            
           Error	1	'MethodParameters' property is read-only and cannot be set from markup. Line 29 Position 7.	C:\dev\workspaces\dotnet\microsoft\wpf\src\assemblies\enumInXaml\enumInXamldemo\MainWindow.xaml	29	7	enumInXamldemo
 
           -->
<!--       <ObjectDataProvider MethodName="GetValues"        
                          ObjectType="{x:Type sys:Enum}"        
                          x:Key="ExampleEnumValues"
                          MethodParameters="{StaticResource valueToPassIn}">
            </ObjectDataProvider>-->

            <!-- Inline the MethodParameters because ObjectDataProvider does not support it in the Property attribute   -->
            <ObjectDataProvider MethodName="GetValues"        
                  ObjectType="{x:Type sys:Enum}"        
                  x:Key="EnumValuesSource2"
                                >
                <ObjectDataProvider.MethodParameters>
                    <StaticResourceExtension ResourceKey="valueToPassIn" />
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>


            <!-- Since "ExampleEnumValues" shown above does not work with property attribute, we changed to use Property Element -->
            <ObjectDataProvider MethodName="GetValues"        
                  ObjectType="{x:Type sys:Enum}"        
                  x:Key="EnumValuesSource3"
                                >
                <ObjectDataProvider.MethodParameters>
                    <x:TypeExtension Type="{x:Type local:MyEnum}" />
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>

            <!-- You can also improve the way in EnumValueSoruce2, but this time use "Type" member.  -->
            <x:Type x:Key="typeToPassIn2" Type="{x:Type local:MyEnum}" />
            <ObjectDataProvider MethodName="GetValues"        
                  ObjectType="{x:Type sys:Enum}"        
                  x:Key="EnumValuesSource4"
                                >
                <ObjectDataProvider.MethodParameters>
                    <StaticResourceExtension ResourceKey="typeToPassIn2" />
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
            
            <!--
            
            Pass Enum values when the Enum is from another containing class
            
              http://stackoverflow.com/questions/359699/passing-an-enum-value-as-command-parameter-from-xaml
            
            see the answer from "tbergelt"
            
            
            -->
            
            
            <!-- In case that the Enum is defined inside another class
            
               such as the        enumInXamldemo.OuterClass.MyEnum    
            -->

            <x:Array Type="{x:Type local:OuterClass+MyEnum}" x:Key="EnumInAnotherClass">
                <x:Static Member="local:OuterClass+MyEnum.Value1" />
                <x:Static Member="local:OuterClass+MyEnum.Value2" />
                <x:Static Member="local:OuterClass+MyEnum.Value2" />
            </x:Array>

        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        
        <ComboBox
            x:Name="EnumComboBox" 
            ItemsSource="{Binding Source={StaticResource EnumInAnotherClass}}"
            />
            
    </Grid>
    
</Window>

 

 

References.

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics