做.NET整整一年半了,天天混日子,技術也不行,渾渾噩噩的,過的平淡啊,偶爾出去自助游,總尋思着是不是要干點什么,原因無他,以前的日子太單調,想換個口味。
這不最近做了一個WPF項目,項目做完了,閑下來了,就不知道做什么了,上班嗎,總得為自己找點事做,天天上網,瀏覽網頁,聊天(把妹除外),聽音樂,
天天反反復復的搞這些個有的沒的事,說真的,沒勁,還不如搞一些有實際的事,這樣的事搞多了,你想要的東西或許會來的哦。
我一直認為我寫這個總結是迫於無賴啊,卻又不得不寫,Why? 因為沒有多余的錢出去旅游,太多我想去的地方不能去,想待的地方不能待,記得上次自己一個人
跑到杭州西湖那邊去,什么都沒有就一個包包,看着別人手里拿着各種設備,徹底的疼了,回來一想還是安心的待在蘇州吧,安心工作,提升自己的實力吧。
但是怎么樣提升自己的實力了,我ASP.NET不懂,WCF也不會,WPF連門也沒有入,一句話什么都不懂,唯一會那么一丁點的就是總結。
前天因為要改點東西,打開了我最近做的一個WPF項目,說實話,我下面要寫的東西沒有一點技術含量,沒有任何亮點,沒有任何美感。
下面我們來說說需求吧:
我這個項目屬於工廠監控的項目,例如客戶那邊有一條生產線,有10台機器,#1,#2.....#10,代表10台機器的編號,這10台機器類型相同,所產生的數據
類型是一致的,數據顯示以網格形式顯示。
如下圖:
其實實際的需求比上面要求多一點,要求數據是實時更新,並且特定的數據顯示特定的顏色,值類型的數據顯示的背景色會根據定義的
顏色取值范圍而 顯示顏色。
下面是我依據項目敲的一個范例:
第一步 先看一下這個列子的項目截圖:
第二步 思路介紹
實現的思路:在主界面先制定好整個GridView的排列形式,然后通過后台添加控件的方式來逐一添加數據(10台機械所產生的參數類型一致)。
主界面設計如下圖:
接下來就是WPF前台代碼的布局了...
代碼如下:

<Window x:Class="WPFDemoOne.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="1048" Height="576"> <Border Background="#B3B3B3"> <Grid Grid.Column="0" Background="#50585D" TextBlock.Foreground="#FFFFFF" x:Name="XXOOGrid" TextBlock.FontSize="18" > <Grid.ColumnDefinitions> <ColumnDefinition Width="70"/> <ColumnDefinition Width="85"/> <ColumnDefinition Width="115"/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Border BorderBrush="#252525" BorderThickness="1 1 0 0" Grid.ColumnSpan="3"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="xxxxoooo"/> </Border> <Border BorderBrush="#252525" BorderThickness="1 1 0 0" Grid.ColumnSpan="3" Grid.Row="1" > <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="xxoo"/> </Border> <Border BorderBrush="#252525" BorderThickness="1 1 0 0" Grid.ColumnSpan="3" Grid.Row="2" > <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="xxoo"/> </Border> <Border BorderBrush="#252525" BorderThickness="1 1 0 0" Grid.ColumnSpan="3" Grid.Row="3" > <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="xxoo"/> </Border> <Border BorderBrush="#252525" BorderThickness="1 1 0 0" Grid.Row="4" Grid.ColumnSpan="3"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="xxoo"/> </Border> <Border BorderBrush="#252525" BorderThickness="1 1 0 1" Grid.Row="5" Grid.ColumnSpan="3"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="xxoo"/> </Border> <Border Grid.Column="0" Grid.RowSpan="6" BorderBrush="#252525" BorderThickness="1 1 0 0" Grid.Row="6"> <TextBlock Text="xxoo" Width="72" FontSize="12" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"/> </Border> <Border BorderBrush="#252525" Grid.Column="1" Grid.Row="6" BorderThickness="1 1 0 0" Grid.RowSpan="2"> <TextBlock Text="xxoo" Width="60" FontSize="12" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"/> </Border> <Border BorderBrush="#252525" Grid.Column="2" Grid.Row="6" BorderThickness="1 1 0 0"> <TextBlock Text="xxoo" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> <Border BorderBrush="#252525" Grid.Column="2" Grid.Row="7" BorderThickness="1 1 0 0"> <TextBlock Text="xxoo" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> <Border BorderBrush="#252525" Grid.Column="1" Grid.Row="8" BorderThickness="1 1 0 0" Grid.RowSpan="4"> <TextBlock Text="xxoo" Width="80" FontSize="12" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"/> </Border> <Border BorderBrush="#252525" Grid.Column="2" Grid.Row="8" BorderThickness="1 1 0 0"> <TextBlock Text="xxoo" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> <Border BorderBrush="#252525" Grid.Column="2" Grid.Row="9" BorderThickness="1 1 0 0"> <TextBlock Text="xxoo" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> <Border BorderBrush="#252525" Grid.Column="2" Grid.Row="10" BorderThickness="1 1 0 0"> <TextBlock Text="xxoo" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> <Border BorderBrush="#252525" Grid.Column="2" Grid.Row="11" BorderThickness="1 1 0 0"> <TextBlock Text="xxoo" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> </Grid> </Border> </Window>
在讓我們看看,Data.cs里面的代碼吧。
在這個里面我定義了Name和value字段,value是顯示在gridview里面的值。value值改變通知變更的有兩個:value和Background。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Media; using System.ComponentModel; using WPFDemoOne; namespace WPFDemoOne { public class Demo:NotifyModel { public Demo() { } private string value; public string Value { get { return this.value; } set { this.value = value; NotifyPropertyChanged(()=>Value); NotifyPropertyChanged(()=>Background); } } private string name; public string Name { get { return name; } set { name = value; NotifyPropertyChanged(()=>Name); } } public SolidColorBrush Background { get { return GetColor(Value); } } SolidColorBrush titleBack = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0xB8, 0xCE, 0xDA) }; SolidColorBrush defaultBack = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0xE6, 0xE6, 0xE6) }; SolidColorBrush alarmBack = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00) }; SolidColorBrush alarmYellow = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00) }; SolidColorBrush alarmGreen = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0x00, 0xFF, 0x03) }; SolidColorBrush alarmGrey = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0x80, 0x80, 0x80) }; private SolidColorBrush GetColor(string value) { if (!string.IsNullOrEmpty(value)) { if (Name == "9") { return alarmBack; } if (Name == "8") { return alarmYellow; } if (Name == "7") { return alarmGreen; } if (Name == "6") { return alarmGrey; } } return defaultBack; } } }
在來看一下NotifyModel.cs里面的代碼吧。
其實這段代碼是借鑒開源框架里面的東西,我注釋的東西可能有問題,不怕誤導的盡管看。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Linq.Expressions; namespace WPFDemoOne { public class NotifyModel:INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public virtual void NotifyPropertyChanged<TProperty>(Expression<Func<TProperty>> property) { //創建一個lamdba的表達式,並獲取其中的代碼塊 var lamdba=(LambdaExpression)property; MemberExpression meberExpression;//訪問字段或者屬性 //如果代碼主題包含lamdba表達式 if (lamdba.Body is UnaryExpression) { //把主題轉換成lamdba表達式 var unaryExpression = (UnaryExpression)lamdba.Body; //獲取后面的字段名 meberExpression = (MemberExpression)unaryExpression.Operand; } else { //直接獲取后面的字段名 meberExpression = (MemberExpression)lamdba.Body; } NotifyPropertyChanged(meberExpression.Member.Name); } } }
最后一個就是主界面的后台代碼。
申明一點,其實項目中不是這樣做的,建了一個gridHelper類,里面的數據也不是自己添加的,數據格式已經規定好了的,通過XML配置,來確定某一行的數據和取得數據的格式。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Threading; using System.Collections.ObjectModel; namespace WPFDemoOne { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); new Thread(new ThreadStart(Update)).Start(); CreateCol(); Loaded += new RoutedEventHandler(XXOOGrid_Load); Unloaded += new RoutedEventHandler(XXOOGrid_UnLoad); } ObservableCollection<ObservableCollection<Demo>> listKeys = new ObservableCollection<ObservableCollection<Demo>>(); private void Update() { while (true) { while (isUpdate) { //執行客戶端UpdateData方法,刷新所有數據 App.Current.Dispatcher.Invoke(new Action(UpdateData)); Thread.Sleep(1000); } Thread.Sleep(5000);//刷新時間 if (!isUpdate) { break; } } } private void UpdateData() { //調用刷新數據的方法 RefreshDatas(); } private void CreateCol() { InitKeys(); //定義三種邊框樣式 var thick = new Thickness(1, 1, 0, 0); var thickcollast = new Thickness(1, 1, 1, 0); var thickrowlast = new Thickness(1, 1, 0, 1); var thickrowcollast = new Thickness(1, 1, 1, 1); //10代表有幾列,為表頭賦值 for (int i = 0; i < 10; i++) { //i+3是因為主界面左邊有三列,如果是一列則改為i+1 BuildItem(new Demo() { Value = "#" + (i + 1) }, thick, "Value", 0, i + 3); } for (int i = 0; i < listKeys.Count; i++) { var row = listKeys[i]; for (int col = 0; col < row.Count; col++) { var key = row[col]; //如果不是最后一行和最后一列 if (col != row.Count - 1 && i != listKeys.Count - 1) { //i+1,因為表頭已經賦值,故而是i+1,表頭為#1,#2......#10 BuildItem(key, thickcollast, "Value", i + 1, 3 + col); } //不是第最后一行,但是最后一列 else if (col != row.Count - 1 && i == listKeys.Count - 1) { BuildItem(key, thickrowlast, "Value", i + 1, 3 + col); } else { BuildItem(key, thickrowcollast, "Value", i + 1, 3 + col); } } } } /// <summary> /// 創建textBlock並存放Value,border存放textBlock /// </summary> /// <param name="key">某一行一列對應的對象,例如第一行第一列的數據</param> /// <param name="thick">邊框的樣式</param> /// <param name="item">某一行一列對應的對象顯示的字段</param> /// <param name="row">行是主界面的第幾行</param> /// <param name="col">列是主界面的第幾列</param> private void BuildItem(Demo key, Thickness thick, string item, int row, int col) { var text = new TextBlock(); text.VerticalAlignment = System.Windows.VerticalAlignment.Center; text.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; text.SetBinding(TextBlock.TextProperty, item);//賦值 text.Foreground = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0x25, 0x25, 0x25) }; text.FontSize = 8; text.FontWeight = FontWeights.Bold; text.DataContext = key; var border = new Border(); border.BorderBrush = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0x25, 0x25, 0x25) }; border.BorderThickness = thick; border.Child = text; border.SetValue(Grid.RowProperty, row); border.SetValue(Grid.ColumnProperty, col); //設定第一行的顏色 if (row == 0) { border.Background = new SolidColorBrush() { Color = Color.FromArgb(0xFF, 0xB8, 0xCE, 0xDA) }; } //其他行的顏色 else { border.SetBinding(Border.BackgroundProperty, "Background"); border.DataContext = key; } XXOOGrid.Children.Add(border); } /// <summary> /// 循環遍歷每一行並賦值 /// </summary> private void RefreshDatas() { foreach (var row in listKeys) { foreach (var m in row) { // var values = GetTagValue(m.Value); var value = m.Value; if (value == "NumberOne") { value = "1"; } if (m.Value != value) { m.Value = value; } } } } /// <summary> /// 備用方法, /// </summary> /// <param name="value"></param> /// <returns></returns> private string GetTagValue(string value) { //從這里獲取數據的值,並替換成自己想要的值,例如value="NumberOne" return value; } void XXOOGrid_Load(object sender, RoutedEventArgs e) { isUpdate = true; } void XXOOGrid_UnLoad(object sender, RoutedEventArgs e) { isUpdate = false; } protected override void OnClosed(EventArgs e) { isUpdate = false; } private void InitKeys() { //從SQL或者XML中讀取數據,這里是我自己手動給的數據 ObservableCollection<Demo> demoOne = new ObservableCollection<Demo>() { new Demo(){ Name="1",Value="NumberOne"}, new Demo(){ Name="2",Value="NumberTwo"}, new Demo(){ Name="3",Value="NumberThree"}, new Demo(){ Name="4",Value="NumberFour"}, new Demo(){ Name="5",Value="NumberFive"}, new Demo(){ Name="6",Value="NumberSix"}, new Demo(){ Name="7",Value="NumberSeven"}, new Demo(){ Name="8",Value="NumberEight"}, new Demo(){ Name="9",Value="NumberNine"}, new Demo(){ Name="10",Value="NumberTen"} }; listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); listKeys.Add(demoOne); } public bool isUpdate { get; set; } } }
就這些了,哎,第一篇博客不容易,這是我頭一次寫這么長的東東,學不進去新的東西,只能鞏固一下自己原有的知識,雖然東西有點簡單,但是勝在是我第一次總結自己的項目。
有碼有真相/Files/xuliangjie/GridView.rar