WPF 數據綁定TreeView+DataGrid+XML


學習WPF做的一個數據綁定例子,可供學習參考。

實現功能:WPF通過讀取XML數據綁定到TreeView, 在通過TreeView選擇項(Node)獲取的對應的數據綁定到DataGrid控件上,再通過DataGrid選中行的詳細信息數據綁定到DataGrid。

首先創建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中數據:

 public class GetData
    {
        private string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "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;
        }
    }

創建一個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="WPF.TreeView.DataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:WPF.TreeView.DataGrid.ViewModel" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <src:ViewModel></src:ViewModel>
    </Window.DataContext>
    <Window.Resources>
        <HierarchicalDataTemplate x:Key="treeData"
                                      ItemsSource="{Binding Path=Products}" >
            <TextBlock Text="{Binding Path=Name}"></TextBlock>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"></ColumnDefinition>
            <ColumnDefinition Width="10"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="10"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
       
        <TreeView Name="tree"  ItemsSource="{Binding Path=GetCategories}"  ItemTemplate="{StaticResource ResourceKey=treeData}"   Grid.RowSpan="3"></TreeView>
        <DataGrid Name="dataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding ElementName='tree', Path=SelectedItem.Orders}" Grid.Column="2" Grid.Row="0">
            <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>

實現效果如圖:

 


免責聲明!

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



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