WPF 之使用Treeview和DataGrid的关联绑定

2017-08-04 19:37:41来源:CSDN作者:qq_34057374人点击

分享

实现功能:WPF通过读取XML数据绑定到TreeView, 在通过TreeView选择项(Node)获取的对应的数据绑定到DataGrid控件上,再通过DataGrid选中行的详细信息数据绑定到另一个DataGrid。

首先创建XML数据. 名称为 Order.xml

<?xml version="1.0" encoding="utf-8" ?><root>  <category name="Computer">    <product name="联想笔记本">      <order orderId="1" orderName="cizon的订单" orderDate="2012-11-10">        <orderInfo productName="联想笔记本" unitPrice="3000" count="2">         </orderInfo>      </order>      <order orderId="2" orderName="steven的订单" orderDate="2012-11-10">        <orderInfo productName="联想笔记本" unitPrice="3000" count="2">        </orderInfo>      </order>    </product>    <product name="宏基笔记本">      <order orderId="1" orderName="Luly的订单" orderDate="2012-11-10">        <orderInfo productName="宏基笔记本" unitPrice="2000" count="3">        </orderInfo>      </order>      <order orderId="2" orderName="steven的订单" orderDate="2012-11-10">        <orderInfo productName="宏基笔记本" unitPrice="2000" count="3">        </orderInfo>      </order>    </product>    <product name="华硕笔记本"></product>  </category>  <category name="TV">    <product name="海尔电视">      <order orderId="1" orderName="cizon的订单" orderDate="2012-11-10">        <orderInfo productName="海尔电视" unitPrice="1000" count="2">        </orderInfo>      </order>      <order orderId="2" orderName="steven的订单" orderDate="2012-11-10">        <orderInfo productName="海尔电视" unitPrice="1000" count="2">        </orderInfo>      </order>    </product>    <product name="长虹电视">      <order orderId="1" orderName="Luly的订单" orderDate="2012-11-10">        <orderInfo productName="长虹电视" unitPrice="2000" count="3">        </orderInfo>      </order>      <order orderId="2" orderName="steven的订单" orderDate="2012-11-10">        <orderInfo productName="长虹电视" unitPrice="2000" count="3">        </orderInfo>      </order>    </product>    <product name="三星电视"></product>  </category></root>

创建Model实体类:

 public class Category    {       public string Name { get; set; }       public List<Product> Products { get; set; }     } public class Product   {       public string Name { get; set; }       public List<Order> Orders { get; set; }   } public class Order    {      public int OrderId { get; set; }      public string OrderName { get; set; }      public DateTime OrderDate { get; set; }      public decimal TotalPrice { get; set; }      public List<OrderInfo> OrderInfos { get; set; }     } public  class OrderInfo    {      public int OrderId { get; set; }      public string ProductName { get; set; }      public decimal UnitPrice { get; set; }      public int Count { get; set; }    }

创建数据访问类GetData 获取XML中数据:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml.Linq;namespace WpfApplication1{    public class GetData    {        //private string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "OrderData.xml";        private string path = "../../OrderData.xml";        public List<Category> GetCategorys()        {            XElement xElement = XElement.Load(path);            var categorys = (from n in xElement.Elements("category")                             select new Category                             {                                 Name = n.Attribute("name").Value,                                 Products = GetProducts(n)                             }).ToList();            return categorys;        }        private List<Product> GetProducts(XElement xElement)        {            var products = (from n in xElement.Elements("product")                            select new Product                            {                                Name = n.Attribute("name").Value,                                Orders = GetOrders(n)                            }).ToList();            return products;        }        private List<Order> GetOrders(XElement xElement)        {            var orders = (from n in xElement.Elements("order")                          select                              new Order                              {                                  OrderId = Convert.ToInt32(n.Attribute("orderId").Value),                                  OrderName = n.Attribute("orderName").Value,                                  OrderDate = Convert.ToDateTime(n.Attribute("orderDate").Value),                                  TotalPrice = GetTotalPrice(n),                                  OrderInfos = GetOrderInfo(n)                              }).ToList();            return orders;        }        private decimal GetTotalPrice(XElement xElement)        {            decimal totalPrice = 0;            List<OrderInfo> orderInfos = GetOrderInfo(xElement);            foreach (var info in orderInfos)            {                totalPrice += info.UnitPrice * info.Count;            }            return totalPrice;        }        private List<OrderInfo> GetOrderInfo(XElement xElement)        {            var orderInfos = (from n in xElement.Elements("orderInfo")                              select                                  new OrderInfo                                  {                                      OrderId = Convert.ToInt32(n.Parent.Attribute("orderId").Value),                                      ProductName = n.Attribute("productName").Value,                                      UnitPrice = Convert.ToDecimal(n.Attribute("unitPrice").Value),                                      Count = Convert.ToInt32(n.Attribute("count").Value)                                  }).ToList();            return orderInfos;        }    }}

加载的DLL程序集为
这里写图片描述

创建一个ViewModel类实现INotifyPropertyChanged接口通知属性值得改变,实现双向绑定,

public class ViewModel:INotifyPropertyChanged    {        public event PropertyChangedEventHandler PropertyChanged;        GetData getData=new GetData();        private List<Category> _categories;        public List<Category> GetCategories        {            get            {                if(_categories==null)                {                    _categories = getData.GetCategorys();                }                return _categories;            }            set            {                if(value!=_categories)                {                    _categories = value;                    if(PropertyChanged!=null)                    {                        PropertyChanged(this, new PropertyChangedEventArgs("GetCategories"));                    }                }            }        }    }

窗体页面绑定代码

<Window x:Class="WpfApplication1.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:WpfApplication1"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <Window.DataContext>        <local:ViewModel></local:ViewModel>    </Window.DataContext>    <Window.Resources>        <HierarchicalDataTemplate x:Key="treeData" ItemsSource="{Binding Path=Products}">                <TextBlock  Text="{Binding Path=Name}"/>        </HierarchicalDataTemplate>    </Window.Resources>    <Grid>        <Grid.ColumnDefinitions>            <ColumnDefinition Width="180"></ColumnDefinition>            <ColumnDefinition></ColumnDefinition>        </Grid.ColumnDefinitions>        <Grid.RowDefinitions>            <RowDefinition Height="*"></RowDefinition>            <RowDefinition Height="10"></RowDefinition>            <RowDefinition Height="*"></RowDefinition>        </Grid.RowDefinitions>        <TreeView Name="tree" ItemsSource="{Binding GetCategories}" ItemTemplate="{StaticResource ResourceKey=treeData}" Grid.RowSpan="3"/>        <DataGrid Name="dataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding ElementName=tree, Path=SelectedItem.Orders}" Grid.Column="2">            <DataGrid.Columns>                <DataGridTextColumn Binding="{Binding OrderId}" Width="*" Header="订单编号"></DataGridTextColumn>                <DataGridTextColumn Binding="{Binding OrderName}" Width="*" Header="订单名称"></DataGridTextColumn>                <DataGridTextColumn Binding="{Binding OrderDate}" Width="*" Header="订单时间"></DataGridTextColumn>                <DataGridTextColumn Binding="{Binding TotalPrice}" Width="*" Header="总额"></DataGridTextColumn>            </DataGrid.Columns>        </DataGrid>        <DataGrid Name="dataGrid2" AutoGenerateColumns="False" ItemsSource="{Binding ElementName='dataGrid1', Path=SelectedItem.OrderInfos}" Grid.Column="2" Grid.Row="2">            <DataGrid.Columns>                <DataGridTextColumn Binding="{Binding OrderId}" Width="*" Header="订单编号"></DataGridTextColumn>                <DataGridTextColumn Binding="{Binding ProductName}" Width="*" Header="产品"></DataGridTextColumn>                <DataGridTextColumn Binding="{Binding UnitPrice}" Width="*" Header="单价"></DataGridTextColumn>                <DataGridTextColumn Binding="{Binding Count}" Width="*" Header="数量"></DataGridTextColumn>            </DataGrid.Columns>        </DataGrid>    </Grid></Window>

后台代码

    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        private ViewModel _viewModel;        public MainWindow()        {            InitializeComponent();            _viewModel = new ViewModel();            this.DataContext = _viewModel;        }

其中Window.Datacontext的标记是可以注释掉的。
这里写图片描述

整个项目的结构是这样子滴
这里写图片描述

接下来运行起来, 看看效果.
刚开始的界面

选中左边的树节点后,右边DataGrid显示数据
选中上面的DataGrid后,下面的显示详情数据

好了,今天到此为止了。 博主也是刚开始学习WPF呢。 好多都不懂。 本篇文章参考自http://www.cnblogs.com/cizon/archive/2012/11/11/2765596.html

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台