简体   繁体   中英

How to populate a Combobox in a Datagrid that is bound to an Enum in C# WPF

I am looking for a way to populate the datagrid combobox with values from an XML-file. The combobox i bound to an Enum. Passing a string value doesn't work.

I have tried different options for declaring my enum and strings, but this is not the solution.

I have an XML-file like this.

xml
<?xml version="1.0"?>
<UserInfo>
<Users>
<User Name="Donald Duck" Hair="0" />
<User Name="Mimmi Mouse" Hair="3" />
<User Name="Goofy" Hair="2" />
</Users>
</UserInfo>
xaml
    <Window.Resources>
        <ObjectDataProvider x:Key="HairColor" MethodName="GetValues"
                            ObjectType="{x:Type core:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:HairColor"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>

...
        <Grid Margin="10">
            <DataGrid Name="dgUsers" AutoGenerateColumns="False" Margin="227,0,-227,0">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                    <DataGridComboBoxColumn Header="Hair Color" SelectedItemBinding="{Binding Color}" ItemsSource="{Binding Source={StaticResource HairColor}}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
c#
    public partial class MainWindow : Window
    {
        private ObservableCollection<User> users = new ObservableCollection<User>();

        public MainWindow()
        {

            InitializeComponent();

            List<User> users = new List<User>();
            users.Add(new User() { Name = "Donald Duck", Color = "White" });
            users.Add(new User() { FirstName = "Mimmi Mouse", Color = "Red" });
            users.Add(new User() { FirstName = "Goofy", Color = "Brown" });

            dgUsers.ItemsSource = users;
       }




   //Defines the customer object
    public class User
    {
        public string Name { get; set; }
        public string Color { get; set; }
    }

    public enum HairColor { White, Black, Brown, Red, Yellow };

When running the color doesn't show. I want to be able to use the combo for selecting, but it should be populated from the xml-file where the values are numbers. Besides, how do I get the value from the combo-box (numeric)?

here is a solution i use for this case: i suggest you to use MarkupExtension than Objectprovider to create a list of Enum in combobox

MainWindow.xaml.cs:

using System.Windows;

namespace zzWpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
}

MainWindowviewModel.cs:

using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace zzWpfApp1
{
    class MainWindowViewModel
    {
        public ObservableCollection<User> Users { get; set; }

        public MainWindowViewModel()
        {
            List<User> users = new List<User>();
            users.Add(new User() {Name = "Donald Duck", HairColor = HairColor.White});
            users.Add(new User() {Name = "Mimmi Mouse", HairColor = HairColor.Red});
            users.Add(new User() {Name = "Goofy", HairColor = HairColor.Brown});
            Users = new ObservableCollection<User>(users);
        }
    }
}                       

User.cs:

using System.ComponentModel;

namespace zzWpfApp1
{
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum HairColor
    {
        [Description("White")] White,
        [Description("Black")] Black,
        [Description("Brown")] Brown,
        [Description("Red")] Red,
        [Description("Yellow")] Yellow,
    }


    class User : INotifyPropertyChanged
    {
        private string _name;
        private HairColor _haircolor;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                NotifyPropertyChanged("Name");
            }
        }

        public HairColor HairColor
        {
            get { return _haircolor; }
            set
            {
                _haircolor = value;
                NotifyPropertyChanged("HairColor");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

EnumConverter.cs: (generic file)

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Markup;                                                                                          

namespace zzWpfApp1                                                                                               
{
    public class EnumBindingSourceExtension : MarkupExtension
    {
        private Type _enumType;

        public Type EnumType
        {
            get { return this._enumType; }
            set
            {
                if (value != this._enumType)
                {
                    if (null != value)
                    {
                        Type enumType = Nullable.GetUnderlyingType(value) ?? value;

                        if (!enumType.IsEnum)
                            throw new ArgumentException("Type must be for an Enum.");
                    }

                    this._enumType = value;
                }
            }
        }

        public EnumBindingSourceExtension(Type enumType)
        {
            this.EnumType = enumType;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (null == this._enumType)
                throw new InvalidOperationException("The EnumType must be specified.");

            Type actualEnumType = Nullable.GetUnderlyingType(this._enumType) ?? this._enumType;
            Array enumValues = Enum.GetValues(actualEnumType);

            if (actualEnumType == this._enumType)
                return enumValues;

            Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
            enumValues.CopyTo(tempArray, 1);
            return tempArray;
        }
    }

    public class EnumDescriptionTypeConverter : EnumConverter                                                     
    {                                                                                                             
        public EnumDescriptionTypeConverter(Type type)                                                            
            : base(type)                                                                                          
        {                                                                                                         
        }                                                                                                         

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
            object value, Type destinationType)                                                                   
        {                                                                                                         
            if (destinationType == typeof(string))                                                                
            {                                                                                                     
                if (value != null)                                                                                
                {                                                                                                 
                    FieldInfo fi = value.GetType().GetField(value.ToString());                                    
                    if (fi != null)                                                                               
                    {                                                                                             
                        var attributes =                                                                          
                            (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);  
                        return ((attributes.Length > 0) && (!String.IsNullOrEmpty(attributes[0].Description)))    
                            ? attributes[0].Description                                                           
                            : value.ToString();                                                                   
                    }                                                                                             
                }                                                                                                 
                return string.Empty;                                                                              
            }                                                                                                     
            return base.ConvertTo(context, culture, value, destinationType);                                      
        }                                                                                                         
    }                                                                                                             
}   

MainWindow.xaml:

<Window x:Class="zzWpfApp1.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:local="clr-namespace:zzWpfApp1"                                                                                  
        mc:Ignorable="d"                                                                                                       
        Title="MainWindow" Height="450" Width="800">                                                                           
    <Grid>                                                                                                                     
        <Grid Margin="10">                                                                                                     
            <DataGrid Name="dgUsers" AutoGenerateColumns="False" Margin="20,20,300,20" ItemsSource="{Binding Users }">         
                <DataGrid.Columns>                                                                                             
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}" />                                              
                    <DataGridComboBoxColumn Header="Hair Color"  MinWidth="150"                                                
                                            SelectedItemBinding="{Binding HairColor}"                                          
                                            ItemsSource="{Binding Source={local:EnumBindingSource {x:Type local:HairColor}}}"/>
                </DataGrid.Columns>                                                                                            
            </DataGrid>                                                                                                        
        </Grid>                                                                                                                
    </Grid>                                                                                                                    
</Window>         

result:

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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