定制WPF中的DataGrid控件支持對不同的實體類實現中文標題顯示


問題提出:

這是今天被問到的一個問題。情況是這樣的:

我們都知道WPF中有一個用來顯示列表數據的DataGrid控件,而且該控件具有一個AutoGenerateColumns 屬性(默認為true),它可以根據給定的數據,自動地設置列的標題,也就是說,我們可以根據需要讀取不同的實體數據,然后綁定到控件上去,它自己知道該如何創建列,以及顯示數據。

這里的問題在於,我們的實體類定義通常都是英文的,例如下面是一個最簡單的例子

    public class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

DataGrid會自動為每個屬性建立一個列,並且列標題設置為屬性名稱。例如下面這樣:

image

但是,美中不足的是,我們的用戶更喜歡中文的標題。那么,我們是否能夠以最小的代價,讓這些標題能顯示中文呢?

 

解決方案:

首先,我聯想到了MVC中的一個做法,就是需要給實體類添加屬性描述,因為無論如何,我們需要有一個地方可以定義這些中文標題。幸運的是,我們可以直接使用內置的DataAnnotation的功能來實現,例如:

    public class Employee
    {
        [Display(Name="姓氏")]
        public string FirstName { get; set; }
        [Display(Name="名字")]
        public string LastName { get; set; }
    }

備注:這里要先引用System.ComponentModel.DataAnnotations 這個程序集。

 

接下來,我們的問題就是,如何將這里定義好的Display的屬性,讀取到DataGrid的列標題處。我首先想到的是,能否通過定制ColumnHeaderStyle來實現,但經過一些努力,沒有成功。如果有朋友對這個方案有補充,請不吝賜教。

我最后采用的方法是這樣的,DataGrid有一個事件叫:AutoGeneratingColumn  ,顧名思義,這個事件就是在列被創建出來之前觸發的。我通過下面的代碼實現了我們想要的功能。

        private void DataGrid_AutoGeneratingColumn_1(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            var result = e.PropertyName;
            var p = (e.PropertyDescriptor as PropertyDescriptor).ComponentType.GetProperties().FirstOrDefault(x => x.Name == e.PropertyName);

            if (p != null)
            {
                var found = p.GetCustomAttribute<DisplayAttribute>();
                if (found != null) result = found.Name;
            }

            e.Column.Header = result;
        }

這樣一來,我們看到的界面就是下面這樣的啦

image

而且重要的,這個功能是完全通用的,不管日后想要換成什么樣的實體類型,都可以通過定義Display這個Attributel來改變標題。

 

最后,我還這個功能封裝了一下,以便更加好的使用.我做了一個擴展控件,如下所示

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Windows.Controls;

namespace WpfApplication1
{
    class xGrid:DataGrid
    {
        public xGrid()
        {
            AutoGeneratingColumn += (o, e) =>
            {
                var result = e.PropertyName;
                var p = (e.PropertyDescriptor as PropertyDescriptor).ComponentType.GetProperties().FirstOrDefault(x => x.Name == e.PropertyName);

                if (p != null)
                {
                    var found = p.GetCustomAttribute<DisplayAttribute>();
                    if (found != null) result = found.Name;
                }

                e.Column.Header = result;
            };
        }
    }
}

 

這樣的話,在項目中任何頁面上我都可以直接像下面這樣使用這個控件了。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        xmlns:controls="clr-namespace:WpfApplication1"
        Height="350"
        Width="525">
    <Grid>
        <controls:xGrid ItemsSource="{Binding}"></controls:xGrid>
    </Grid>
</Window>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM