學習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>
實現效果如圖:
