Search code examples
c#wpfdata-binding

Wpf combobox binding items to rthe enum items


i tried to bind the items inside my enum to my combobox but it does not work my project looks like this solution

  • project

  • namespace

  • Models

  • inside Models there is a enum named Groep that has 3 items

    but visual studio tells me that Groep does not exist. anybody knows what's wrong I am pretty new to wpf thanks for your help.

<Window x:Class="Telefoon.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:System="clr-namespace:System;assembly=mscorlib"        
        xmlns:local="clr-namespace:Telefoon"
        xmlns:models="clr-namespace:Telefoon.Models"
        mc:Ignorable="d"
        DataContext="Persoon"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ObjectDataProvider x:Key="dataFromEnum" MethodName="GetValues"
                            ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="models:Groep"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <ComboBox ItemsSource="{Binding Source={StaticResource dataFromEnum}}">
            
        </ComboBox>
    </Grid>
</Window>
´´´


Solution

  • This should work ! Just tried your approach in a simple Demo App and everything worked fine. Rebuild the app, restart Visual Studio, check the namespace references! VS will always complain if you put in a new namespace and reference it without rebuilding first, but I assume that's not your problem.

    Here's my demo code

    <Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ObjectDataProvider x:Key="GroepData" 
                            MethodName="GetValues" 
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Groep"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    
    <Grid HorizontalAlignment="Center" VerticalAlignment="Top" Margin="20">
        <ComboBox ItemsSource="{Binding Source={StaticResource GroepData}}" Width="200">
            
        </ComboBox>
    
    </Grid>
    

    Another (cleaner) approach comes from Brian Lagunas. He uses a Custom Markup-Extenstion that he can hen reference in XAML. This is also totally reusable for all enums in your project plus I really like the idea of simply creating your own MarkupExtension for problems like this.

    The Custom Markup-Extension is simply a seperate class that inherits from MarkupExtionsion.

    public class EnumBindingSourceExtension : MarkupExtension
    {
        public Type EnumType { get; private set; }
    
        public EnumBindingSourceExtension(Type enumType)
        {
            if (enumType is null || !enumType.IsEnum)
                throw new Exception("Type null or not an enum");
            else
                EnumType = enumType;
        }
    
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return Enum.GetValues(EnumType);
        }
    }
    

    You can simply use that markup extension when u set up the ItemsSource-Binding of your Combobox.

    <ComboBox ItemsSource="{Binding Source={local:EnumBindingSource {x:Type local:Groep}}}"/>
    

    Hope this helps.

    Greets, Paco