欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

wpf 当DataGrid列模版是ComboBox时,显示信息

程序员文章站 2022-05-10 20:40:44
​ 实际工作中,有时DataGrid控件某一列显示数据是从Enum集合里面选择出来的,那这时候设置列模版为ComboBox就能满足需求。而关于显示的实际内容,直接是Enum的string()返回值可能不太适合,这时候采用System.ComponentModel.Description是一个很好用的 ......

​ 实际工作中,有时datagrid控件某一列显示数据是从enum集合里面选择出来的,那这时候设置列模版为combobox就能满足需求。而关于显示的实际内容,直接是enum的string()返回值可能不太适合,这时候采用system.componentmodel.description是一个很好用的方法。

代码中定义的显示类型是enum,实际结果在description中声明。

定义 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模版:

<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实现代码:

    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代码:

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

    }

最终效果图
wpf 当DataGrid列模版是ComboBox时,显示信息

完整代码