When the stencil wpf DataGrid column is ComboBox, the display information

Practice, sometimes DataGrid control displays data in a column is selected from Enum inside the set, and that this time will be able to set the column ComboBox template to meet the demand. In regard to the actual content of the display, direct Enum is a string () return value may not be suitable, this time using the method System.ComponentModel.Description is a very good use.

Display type code is defined Enum, actual results stated in the Description.

Defined Enum Week

    [System.ComponentModel.Description("星期")]
    public enum Week
    {
        [System.ComponentModel.Description("星期一")]
        Monday,

        [System.ComponentModel.Description("星期二")]
        Tuesday,

        [System.ComponentModel.Description("星期三")]
        Wednesday,

        [System.ComponentModel.Description("星期四")]
        Thursday,

        [System.ComponentModel.Description("星期五")]
        Firday,

        [System.ComponentModel.Description("星期六")]
        Saturday,

        [System.ComponentModel.Description("星期日")]
        Sunday,
    }

DataGrid template:

<Grid.Resources>
    <Style x:Key="DataGridTextColumnStyle" TargetType="{x:Type TextBlock}">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
    </Style>
    
    <Style TargetType="{x:Type DataGrid}">
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Background" Value="#FF8CEB87"/>
        <Setter Property="AutoGenerateColumns" Value="False"/>
        <Setter Property="CanUserAddRows" Value="False"/>
        <Setter Property="CanUserReorderColumns" Value="False"/>
        <Setter Property="CanUserSortColumns" Value="False"/>
        <Setter Property="CanUserResizeColumns" Value="False"/>
        <Setter Property="CanUserResizeRows" Value="False"/>
        <Setter Property="RowHeaderWidth" Value="30"/>
        <Setter Property="RowHeight" Value="30"/>
        <Setter Property="IsReadOnly" Value="True"/>
        <Setter Property="CellStyle">
            <Setter.Value>
                <Style TargetType="DataGridCell">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="ColumnHeaderStyle">
            <Setter.Value>
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="HorizontalContentAlignment" Value="Center"/>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>
</Grid.Resources>

<DataGrid ItemsSource="{Binding TestDatas}" LoadingRow="DataGrid_LoadingRow" Margin="0,0,403.6,10">
    <DataGrid.Resources>
        <ObjectDataProvider x:Key="Weeks" MethodName="GetNames" ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Week"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        
        <local:WeekEnumToDescriptionConvertor x:Key="WeekEnumToDescription"/>
        <local:WeekEnumToComboBoxIndexConvertor x:Key="WeekEnumToComboBoxIndex"/>
    </DataGrid.Resources>
    
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Week" Width ="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding Source={StaticResource Weeks}, Converter={StaticResource WeekEnumToDescription}}"
                              SelectedIndex="{Binding TestWeek, Converter={StaticResource WeekEnumToComboBoxIndex}, UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        
        <DataGridTextColumn Header="Message" 
                            Binding="{Binding TestMsg}" 
                            IsReadOnly="True"
                            ElementStyle ="{StaticResource DataGridTextColumnStyle}"
                            Width ="*"/>
    </DataGrid.Columns>
</DataGrid>

WeekEnumToDescriptionConvertor, WeekEnumToComboBoxIndexConvertor implementation code:

    class WeekEnumToComboBoxIndexConvertor : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((int)(Week)value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((Week)(int)value);
        }
    }

    class WeekEnumToDescriptionConvertor : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var strValue = value as string[];
            if (strValue != null)
            {
                var enValue = new Week[strValue.Length];
                for (int i = 0; i < strValue.Length; i++)
                {
                    if (Enum.TryParse(strValue[i], out enValue[i]))
                        strValue[i] = enValue[i].GetDescription();
                }
            }
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

EnumHelper Code:

    public static class EnumHelper
    {
        public static string GetDescription<T>(this T value) where T : struct
        {
            string result = value.ToString();

            var fi = typeof(T).GetField(result);

            var attributes = (System.ComponentModel.DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(System.ComponentModel.DescriptionAttribute), true);

            if (attributes != null && attributes.Length > 0)
            {
                return attributes[0].Description;
            }
            return result;
        }

        public static T GetValueByDescription<T>(this string description) where T : struct
        {
            Type type = typeof(T);
            foreach (var field in type.GetFields())
            {
                if (field.Name == description)
                {
                    return (T)field.GetValue(null);
                }

                var attributes = (System.ComponentModel.DescriptionAttribute[])field.GetCustomAttributes(
                    typeof(System.ComponentModel.DescriptionAttribute), true);

                if (attributes != null && attributes.Length > 0)
                {
                    if (attributes[0].Description == description)
                    {
                        return (T)field.GetValue(null);
                    }
                }
            }
            throw new ArgumentException(string.Format($"{description} 未能找到对应的枚举"), "Description");
        }

        public static T GetValue<T>(this string value) where T : struct
        {
            T result;
            if (Enum.TryParse(value, true, out result))
            {
                return result;
            }
            throw new ArgumentException(string.Format($"{value} 未能找到对应的枚举"), "Value");
        }

    }

The final renderings

The complete code

Guess you like

Origin www.cnblogs.com/njit-77/p/11516704.html