如何在C#WPF中绑定到枚举的Datagrid中填充Combobox

问题描述 投票:0回答:1

我正在寻找一种方法来使用XML文件中的值填充datagrid组合框。组合框我绑定到Enum。传递字符串值不起作用。

我已经尝试了不同的选项来声明我的枚举和字符串,但这不是解决方案。

我有一个像这样的XML文件。

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 };

运行时颜色不显示。我希望能够使用组合进行选择,但它应该从xml文件中填充,其中值是数字。此外,如何从组合框(数字)中获取值?

c# combobox wpfdatagrid
1个回答
0
投票

这是我用于这种情况的解决方案:我建议你使用MarkupExtension而不是Objectprovider在组合框中创建一个Enum列表

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 :(通用文件)

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>         

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.