自定义“伪GridView”---菜鸟三无残品系列

     

       做.NET整整一年半了,天天混日子,技术也不行,浑浑噩噩的,过的平淡啊,偶尔出去自助游,总寻思着是不是要干点什么,原因无他,以前的日子太单调,想换个口味。

       这不最近做了一个WPF项目,项目做完了,闲下来了,就不知道做什么了,上班吗,总得为自己找点事做,天天上网,浏览网页,聊天(把妹除外),听音乐,

       天天反反复复的搞这些个有的没的事,说真的,没劲,还不如搞一些有实际的事,这样的事搞多了,你想要的东西或许会来的哦。

       我一直认为我写这个总结是迫于无赖啊,却又不得不写,Why? 因为没有多余的钱出去旅游,太多我想去的地方不能去,想待的地方不能待,记得上次自己一个人

       跑到杭州西湖那边去,什么都没有就一个包包,看着别人手里拿着各种设备,彻底的疼了,回来一想还是安心的待在苏州吧,安心工作,提升自己的实力吧。

       但是怎么样提升自己的实力了,我ASP.NET不懂,WCF也不会,WPF连门也没有入,一句话什么都不懂,唯一会那么一丁点的就是总结。

       前天因为要改点东西,打开了我最近做的一个WPF项目,说实话,我下面要写的东西没有一点技术含量,没有任何亮点,没有任何美感。

       下面我们来说说需求吧

             我这个项目属于工厂监控的项目,例如客户那边有一条生产线,有10台机器,#1,#2.....#10,代表10台机器的编号,这10台机器类型相同,所产生的数据

        类型是一致的,数据显示以网格形式显示。

        如下图:                                                                                                                                                                                                            

 

         其实实际的需求比上面要求多一点,要求数据是实时更新,并且特定的数据显示特定的颜色,值类型的数据显示的背景色会根据定义的

    颜色取值范围而  显示颜色。

 

   下面是我依据项目敲的一个范例:

     第一步 先看一下这个列子的项目截图:                      

                                        

    第二步  思路介绍

   实现的思路:在主界面先制定好整个GridView的排列形式,然后通过后台添加控件的方式来逐一添加数据(10台机械所产生的参数类型一致)。

     主界面设计如下图:         

       接下来就是WPF前台代码的布局了...

       代码如下:

       

View Code
<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。

 

View Code
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里面的代码吧。

    其实这段代码是借鉴开源框架里面的东西,我注释的东西可能有问题,不怕误导的尽管看。

View Code
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配置,来确定某一行的数据和取得数据的格式。

View Code
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

 

 

  

 

 

                                          

       

     

posted @ 2012-08-14 13:00  想要飞  阅读(1863)  评论(6编辑  收藏  举报