原文:WPF 实现主从的datagrid以及操作rowdetailtemplate 的方法

WPF 实现主从的datagrid以及操作rowdetailtemplate 的方法

       最近在做一个项目,其中要用到主从表数据的折叠和隐藏,并且对从表中的数据能够获取和操作,虽然搞了好久,但最终被我推敲出来了,写出来分享一下,让朋友少走弯路,废话不说了,先上效果图:

下面是代码:

 
前台   
<DataGrid ItemsSource="{Binding}"Name="dataGrid1"
MouseUp="dataGrid1_MouseUp"...>   
<DataGrid.Columns>   
                   <DataGridTemplateColumn Width="Auto">   
                       <DataGridTemplateColumn.CellTemplate>   
                           <DataTemplate>   
                               <Expander Expanded="Expander_Expanded"Collapsed="Expander_Collapsed"/>   
                           </DataTemplate>   
                       </DataGridTemplateColumn.CellTemplate>   
                   </DataGridTemplateColumn>   
                   <DataGridTextColumn Binding="{Binding Facility_type}"FontSize="22"
Header="設備類型"  
Width=
"120"/>   
                   <DataGridTextColumn  FontSize="22"Header="廠房代碼"
Width="85"
/>   
                   <DataGridTextColumn  FontSize="22" Header="樓層"
Width="70"
/>   
                   <DataGridTextColumn  FontSize="22"  Header="部門名稱"
Width="430"
/>   
                   <DataGridTextColumn Binding="{Binding Count_all}"FontSize="22"   
Header="設備總數" 
Width=
"100"/>   
                   <DataGridTextColumn Binding="{Binding Count_no}"FontSize="25" 
FontWeight="Bold"  
Foreground=
"Red" Header="未使用數量" Width="115"
/>   
                   <DataGridTextColumn Binding="{Binding Count_yes}"FontSize="22" 
Foreground="Green" 
Header=
"使用中數量"  Width="115"/>   
         
               
</DataGrid.Columns>   
               
<DataGrid.RowDetailsTemplate >   
                   <DataTemplate  >   
         
                       <DataGrid Name="dataGrid2" Width="1070" 
SelectedValuePath = "dept_code"
IsReadOnly="True" 
HeadersVisibility=
"None"HorizontalGridLinesBrush="#FFE0E2DF"VerticalGridLinesBrush="#FFE0E2DF"
                                 ItemsSource="{Binding Details}"CanUserAddRows="False"SelectionUnit="FullRow" AutoGenerateColumns="False" MouseUp="dataGrid2_MouseUp">   
                           <DataGrid.Columns>   
                               <DataGridTextColumn   Header=""  Width="150"
/>   
                               <DataGridTextColumn Binding="{Binding building_code}"FontSize="22"
Header="廠房代碼"
Width=
"85"/>   
                               <DataGridTextColumn Binding="{Binding floor}"FontSize="22" 
Header="樓層"
Width=
"70"/>   
                               <DataGridTextColumn Binding="{Binding dept_name}"FontSize="22"  
Header="部門名稱"
Width=
"430"/>   
                               <DataGridTextColumn Binding="{Binding count_all}"FontSize="22"   
Header="設備總數" 
Width=
"100"/>   
                               <DataGridTextColumn Binding="{Binding count_no}" FontSize="25" 
FontWeight="Bold" 
Foreground=
"Red" Header="未使用數量" 
Width="115"
/>   
                               <DataGridTextColumn Binding="{Binding count_yes}"FontSize="22" 
Foreground="Green" 
Header=
"使用中數量"  Width="115"/>   
                           </DataGrid.Columns>   
                    </DataTemplate>   
               
</DataGrid.RowDetailsTemplate>   
...   
</DataGrid>

下面是后台:

 
using System;    
using System.Data;    
using System.Windows;    
using System.Windows.Input;    
using System.Windows.Media;    
using System.Windows.Controls;    
using System.Collections.ObjectModel;    
using System.Windows.Threading;    
namespace
Getac.DSP    
{    
    /// <summary>    
    /// HumanWork.xaml 的交互逻辑    
    /// </summary>    
    publicpartial
class FacilitySum:Window    
    {    
        public string Company_code;    
       // public string Select_item;    
        publicObservableCollection<Facility> Items {
get;set; }    
        privatedelegate
void ThreadDelegate();
//申明一个专用来调用更改线程函数的委托    
     publicDispatcherTimer ShowTimer;    
        publicFacilitySum(string company_code)    
        {    
           
this.Company_code = company_code;    
           
InitializeComponent();    
           
this.WindowState = WindowState.Maximized;    
         
}    
           
        privatevoid
Window_Loaded(object sender, RoutedEventArgs e)    
        {     
          
//datagrid数据的加载    
           
Items = new
ObservableCollection<Facility>();    
           
DataSet dsFacility = newBLL.DSP_FACILITY_USE().GetFacility_status_Sum(Company_code);    
           
DataSet dsFacilityDetail = newBLL.DSP_FACILITY_USE().GetFacility_UseStatus(Company_code);    
           
int count = dsFacility.Tables[0].Rows.Count;    
           
for (inti =
0; i < count; i++)    
           
{    
               
Items.Add(new
Facility(Company_code, i, dsFacility, dsFacilityDetail));    
           
}    
           
dataGrid1.Items.Clear();    
           
dataGrid1.ItemsSource  = Items;    
           
dataGrid1.Items.Refresh();    
           
dataGrid1.SelectedValuePath = "facility_type";    
          
}    
           
        //展开,收缩子表的方法     
        privatevoid
Expander_Expanded(object sender, RoutedEventArgs e)    
        {    
           
DataGridRow row = FindVisualParent<DataGridRow>(sender
as Expander);    
           
row.DetailsVisibility = System.Windows.Visibility.Visible;    
        }    
                    
        privatevoid
Expander_Collapsed(object sender, RoutedEventArgs e)    
        {    
           
DataGridRow row = FindVisualParent<DataGridRow>(sender
as Expander);    
           
row.DetailsVisibility = System.Windows.Visibility.Collapsed;    
        }    
        publicT FindVisualParent<T>(DependencyObject child) where T : DependencyObject    
        {    
           
DependencyObject parentObject = VisualTreeHelper.GetParent(child);    
           
if (parentObject ==
null) returnnull;    
           
T parent = parentObject asT;    
           
if (parent != null)    
               
return parent;    
           
else
               
return FindVisualParent<T>(parentObject);    
        }    
        
//下面的方法曾让我教头烂额,感叹微软的控件封装的太牛逼了,处理起来有点变态    
        /// <summary>    
        /// 找到行明细中嵌套的控件名称    
        /// </summary>    
        /// <typeparam name="T"></typeparam>    
        /// <param name="parent"></param>    
        /// <param name="name"></param>    
        /// <returns></returns>    
        publicT FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject    
        
{    
            
if(parent !=null)    
            
{    
                for(inti=0;i<VisualTreeHelper.GetChildrenCount(parent);i++)    
                {    
                    var
child = VisualTreeHelper.GetChild(parent, i)as
DependencyObject;    
                    string controlName=child.GetValue(Control.NameProperty)as
string;    
                    if(controlName==name)    
                    {    
                        return
child as
T;    
                    }    
                    else
                    {    
                        T result=FindVisualChildByName<T>(child,name);    
                        if(result!=null)    
                            return
result;    
                    }    
                }    
            
}    
            
return null;    
        
}    
           
        
//父表的事件处理驱动    
        privatevoid
dataGrid1_MouseUp(object sender, MouseButtonEventArgs e)    
       
{    
           
if (dataGrid1.CurrentCell.Column !=null
&& dataGrid1.CurrentCell.Column.Header!=null)    
           
{    
               string facility_type = (dataGrid1.Columns[1].GetCellContent(dataGrid1.CurrentCell.Item)as
TextBlock).Text;    
               string head = dataGrid1.CurrentCell.Column.Header.ToString();    
                 //这边可以根据实际写自己的一些方法    
            
}    
       
}    
           
      //字表,也就是rowdetailtemplate中的datagrid 的事件处理方法,其中有调用上面的约束泛型类型的方法。    
       
private void
dataGrid2_MouseUp(object sender, MouseButtonEventArgs e)    
       
{    
            
//下面的两行代码很关键    
       
DataGridRow dgr = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(this.dataGrid1.SelectedIndex);    
           
DataGrid dg= FindVisualChildByName<DataGrid>(dgr,
"dataGrid2") asDataGrid;    
            
//获取鼠标点击的行每一单元格的值   
           
string facility_type = (dataGrid1.Columns[1].GetCellContent(dataGrid1.CurrentCell.Item)as
TextBlock).Text;    
           
string building_code = (dg.Columns[1].GetCellContent(dg.CurrentCell.Item)as
TextBlock).Text;    
           
string floor = (dg.Columns[2].GetCellContent(dg.CurrentCell.Item)as
TextBlock).Text;    
           
string dept_code =dg.SelectedValue.ToString();    
           
string head = dg.CurrentCell.Column.Header.ToString();    
           
//获得一些信息后你可以自己写方法实现需要的功能    
       
}    
    }    
    // 定义集合类用于存放栏位值    
    publicclass
Facility    
    {    
       
//static string FACILITY_TYPE;    
       
public string Facility_type{get;
set; }    
       
public string Building_code {get;
set; }    
       
public string Floor {
get; set; }    
       
public string Dept_code {get;
set; }    
       
public string Count_all {get;
set; }    
       
public string Count_no {get;
set; }    
       
public string Count_yes {get;
set; }    
       
public ObservableCollection<Facility_Detail> Details {get;
set; }    
       
public Facility(string company_code,int
row_index,DataSet dsfacilitySum ,DataSet dsFacilityDetail)    
       
{    
           
           
Facility_type = dsfacilitySum.Tables[0].Rows[row_index]["facility_type"].ToString();    
           
Count_all = dsfacilitySum.Tables[0].Rows[row_index]["count_all"].ToString();    
           
Count_no = dsfacilitySum.Tables[0].Rows[row_index]["count_no"].ToString();    
           
Count_yes = dsfacilitySum.Tables[0].Rows[row_index]["count_yes"].ToString();    
           
Details = new
ObservableCollection<Facility_Detail>();    
           
//详细信息    
       
System.Data.DataTable dtDetail = newSystem.Data.DataTable();    
           
DataRow[] rowDetail = dsFacilityDetail.Tables[0].Select("facility_type='"+ Facility_type +
"'");    
           
dtDetail = dsFacilityDetail.Tables[0].Clone();    
            
foreach (DataRow dr inrowDetail)    
            
{    
                Details.Add(newFacility_Detail()    
                {    
                    facility_type = Facility_type,    
                    building_code = dr["building_code"].ToString(),    
                    floor = dr["floor"].ToString(),    
                    dept_code = dr["dept_code"].ToString(),    
                    dept_name = dr["dept_name"].ToString(),    
                    count_all = dr["count_all"].ToString(),    
                    count_no = dr["count_no"].ToString(),    
                    count_yes = dr["count_yes"].ToString()    
                });    
            
}    
       
}    
    }    
    publicclass
Facility_Detail    
    {  //定义属性 
       
public string facility_type {get;
set; }    
       
public string building_code {get;
set; }    
       
public string floor {
get; set; }    
       
public string dept_code {get;
set; }    
       
public string dept_name {get;
set; }    
       
public string count_all {get;
set; }    
       
public string count_no {get;
set; }    
       
public string count_yes {get;
set; }    
    }    
}

代码虽然很多,但是看下来不觉得繁琐。在这里还要感叹一下,微软的东西,尤其是控件这种东西封装的太死了,你用第三方的控件其实还不如自己写,能明白很多东西。欢迎大家批评指正。

WPF 实现主从的datagrid以及操作rowdetailtemplate 的方法的更多相关文章

  1. easyui datagrid 动态操作editor 的方法

    easyui本身是不提供这么细节的功能的,需要我们自己拓展下: 在easyui.min.js中扩展: $.extend($.fn.datagrid.methods, { addEditor : fun ...

  2. WPF+MVVM学习总结 DataGrid简单案例

    一.WPF概要 WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分.它提供了统一的 ...

  3. MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件

    原文  MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件 UI 前沿技术 WPF 中的多点触控操作事件 Charles Petzold 下载代码示例 就在过去几年,多点触控还只是科幻电 ...

  4. WPF DataGrid 列宽填充表格方法

    WPF中使DataGrid 列宽填充表格方法,设置ColumnWidth属性为ColumnWidth="*"即可. 源码: <DataGrid AutoGenerateCol ...

  5. Asp.Net MVC +EntityFramework主从表新增编辑操作的实现(删除操作怎么实现?)

    Asp.Net MVC +EntityFramework主从表新增编辑操作的实现 对于MVC中同时对主从表的表单操作在网上现有的解决很少,而这样的操作在做业务系统中是经常为遇到的.我在网上搜索了很久都 ...

  6. WPF Window背景半透明 ,蒙版操作实现

    原文:WPF Window背景半透明 ,蒙版操作实现 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/detail ...

  7. WPF自定义样式篇-DataGrid

    WPF自定义样式篇-DataGrid 先上效果图: 样式:  <!--DataGrid样式-->    <Style TargetType="DataGrid"& ...

  8. MVVM框架从WPF移植到UWP遇到的问题和解决方法

    MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...

  9. 一些ES5的操作数组的方法

    在ES5规范中新增了不少操作数组的方法,特此罗列一下以备使用 1. forEach循环 有点类似jQuery的each循环 [12,23,36,4,5].forEach(function(v,k){ ...

随机推荐

  1. Java集合之TreeMap源码分析

    一.概述 TreeMap是基于红黑树实现的.由于TreeMap实现了java.util.sortMap接口,集合中的映射关系是具有一定顺序的,该映射根据其键的自然顺序进行排序或者根据创建映射时提供的C ...

  2. Kotlin入门(1)搭建Kotlin开发环境

    Kotlin做为一门编程语言,已经出现好几年了,但此前在国内并不闻名.自从5月份谷歌宣布它成为Android的官方开发语言之后,Kotlin猛然窜红了,虽说短期内Kotlin无法取代Java,但对于一 ...

  3. fedora 28 , firewalld 防火墙控制,firewall-cmd 管理防火墙规则

    今天,在使用fedora时,需要修改防火墙规则,一时间忘记了命令是什么,这里进行记录一下. 目前 fedora 28/ centos 7 使用 firewalld 作为防火墙软件:下面我就怎么简单管理 ...

  4. vmware linux 虚拟机开机状态加硬盘

    在开机状态先加一块盘,如图: 在系统中查看当前硬盘状态: 新加的硬盘还没刷出来.执行如下命令再试一下: $ echo "- - -" >/sys/class/scsi_hos ...

  5. cmder个人配置文件,做个记录

    以下附件是自己的cmder配置文件: https://app.yinxiang.com/shard/s13/res/30e84035-5f0f-4baf-b18c-a84ce45ec8b9/wkkcm ...

  6. zabbix使用自定义脚本监控内存

    我这里的脚本是监控centos7系统的内存.centos7系统的内存如何查看我之前的博客都是有的.这里直接写了监控步骤 1.首先是编写脚本. #!/bin/bash mem_total(){ TOTA ...

  7. zabbix实现微信告警配置

    zabbix设置微信报警的配置过程 zabbix的报警方式有很多,在这里我们来详细说明一下如何通过微信报警 微信企业号的申请 注册的地址https://qy.weixin.qq.com/  这样企业就 ...

  8. C语言变量定义与数据溢出(初学者)

    1.变量定义的一般形式为:类型说明符.变量名标识符等:例:int a,b,c;(abc为整型变量) 在书写变量定义时应注意以下几点: (1)允许在一个类型说明符后,定义多个相同类型的变量.各变量之间用 ...

  9. 个人技术博客——linux服务器配置以及flask框架

    本次的软件工程实践,我负责我们组后台服务的搭建,我选用了bandwagon的服务器,安装的是Debian GNU/Linux,全程在root用户下操作,后端服务是用python的flask框架,数据库 ...

  10. [Jenkins] 如何修改jenkins上的环境变量

    现象 当本地的环境变量发生变化时,在jenkins 构建时里面访问的环境变量仍是之前旧的(未更新的)导致构建出现错误,比如我以我所遇到的问题进行简单写下,下面例子中我是涉及到修改 PYTHONPATH ...