zoukankan      html  css  js  c++  java
  • WPF TreeView的使用

    WPF提供了treeView控件,利用该控件开发者可以将数据分层显示在树结构中。当然其中需要用到Binding的机制,有用的类包括:ObjectDataProvider、DataTemplate、HierarchicalDataTemplate、ItemsSource等等。

    您可以用声明的方式解释 WPF 应如何通过分层数据模板呈现分层数据。利用 HierarchicalDataTemplate 类这一工具可以弥补复杂数据结构与该数据的直观表示之间的缺口。它与常用 DataTemplate 非常相似,但还允许您指定数据对象子项的来源。您还可以为 HierarchicalDataTemplate 提供一个用于呈现这些子项的模板。

    public class Customer
    {
        public string Name { get; set; }
        public List<Order> Orders { get; set; }
    
        public override string ToString()
        {
            return this.Name;
        }
    }
    
    public class Order
    {
        public string Desc { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }
    
        public override string ToString()
        {
            return this.Desc;
        }
    }
    
    public class OrderDetail
    {
        public string Product { get; set; }
        public int Quantity { get; set; }
    }

    假定您现在要在一个 TreeView 控件中显示上面代码中展现的数据。该 TreeView 控件看上去可能有些类似于图 1。实现此控件需要使用两个 HierarchicalDataTemplate 和一个 DataTemplate。

    图 1 在 TreeView 中显示整个数据层次结构

    这两个分层模板可显示 Customer 对象和 Order 对象。由于 OrderDetail 对象没有任何子项,您可以通过非分层 DataTemplate 呈现这些对象。TreeView 的 ItemTemplate 属性会将该模板用于 Customer 类型的对象,因为 Customer 是包含在 TreeView 根层级下的数据对象。下列代码中所列的 XAML 表明了如何将所有这些方式有机地结合在一起。

    <Grid>
      <Grid.DataContext>
        <!-- 
        This sets the DataContext of the UI
        to a Customers returned by calling
        the static CreateCustomers method. 
        -->
        <ObjectDataProvider 
          xmlns:local="clr-namespace:VariousBindingExamples"
          ObjectType="{x:Type local:Customer}"
          MethodName="CreateCustomers"
          />
      </Grid.DataContext>
    
      <Grid.Resources>
        <!-- ORDER DETAIL TEMPLATE -->
        <DataTemplate x:Key="OrderDetailTemplate">
          <TextBlock>
            <Run>Product:</Run>
            <TextBlock Text="{Binding Path=Product}" />
            <Run>(</Run>
            <TextBlock Text="{Binding Path=Quantity}" />
            <Run>)</Run>
          </TextBlock>
        </DataTemplate>
    
        <!-- ORDER TEMPLATE -->
        <HierarchicalDataTemplate 
          x:Key="OrderTemplate"
          ItemsSource="{Binding Path=OrderDetails}"
          ItemTemplate="{StaticResource OrderDetailTemplate}"
          >
          <TextBlock Text="{Binding Path=Desc}" />
        </HierarchicalDataTemplate>
    
        <!-- CUSTOMER TEMPLATE -->
        <HierarchicalDataTemplate 
          x:Key="CustomerTemplate"
          ItemsSource="{Binding Path=Orders}"
          ItemTemplate="{StaticResource OrderTemplate}"
          >
          <TextBlock Text="{Binding Path=Name}" />
        </HierarchicalDataTemplate>
      </Grid.Resources>
    
      <TreeView
        ItemsSource="{Binding Path=.}"
        ItemTemplate="{StaticResource CustomerTemplate}"
        />
    </Grid>

    我为 Grid(包含 TreeView )的 DataContext 分配了一个 Customer 对象集合。这在 XAML 中通过使用 ObjectDataProvider 即可实现,它是从 XAML 调用方法的一种便捷方式。由于 DataContext 是在元素树中自上而下地继承,因此 TreeView 的 DataContext 会引用这组 Customer 对象。这就是我们可以为其 ItemsSource 属性提供一个 "{Binding Path=.}" 绑定的原因,通过这种方式可以表明 ItemsSource 属性被绑定到 TreeView 的 DataContext。

    如果没有分配 TreeView 的 ItemTemplate 属性,则 TreeView 将仅显示顶层的 Customer 对象。由于 WPF 不知道如何呈现 Customer,因此它会对每个 Customer 都调用 ToString,并为每项都显示该文本。它无法确定每个 Customer 都有一个与其关联的 Order 对象列表,且每个 Order 都有一个 OrderDetail 对象列表。由于 WPF 无法理解您的数据架构,因此您必须向 WPF 解释架构,使它能正确呈现数据结构。

    向 WPF 解释数据的结构和外观是 HierarchicalDataTemplates 的份内工作。此演示中所使用的模板包含的可视元素树非常简单,就是其中带有少量文本的 TextBlocks。在更复杂的应用程序中,模板可能包含交互式的旋转 3D 模型、图像、矢量绘图、复杂的 UserControl 或任何其他可视化基础数据对象的 WPF 内容。

    需要特别注意声明模板的顺序。必须先声明一个模板后才能通过 StaticResource 扩展对其进行引用。这是由 XAML 阅读器规定的要求,该要求适用于所有资源,而不仅仅是模板。

    或者可通过使用 DynamicResource 扩展来引用模板,在这种情况下,模板声明的词汇顺序无关紧要。但使用 DynamicResource 引用(而不是 StaticResource 引用)总会带来一些运行时开销,因为它们要监控资源系统的更改。由于我们不会在运行时替换模板,因此这笔开销是多余的,最好使用 StaticResource 引用并恰当地安排模板声明的顺序。

    ObjectDataProvider:

    ObjectDataProvider提供了绑定任意.net类型的功能,具体功能如下:

    1. ObjectDataProvider提供了绑定任意CLR类型的公嫩那个。
    2. 它可以再XAML中利用生命史的语言以及参数化的构造函数完成对数据的创建
    3. 增加对成员函数的绑定
    4. 提供了更多的异步绑定的功能

    下面使用代码方式声明ObjectDataProvider:

    1、加法类和方法

    class Calculator
        {
            //加法
            public string Add(string arg1, string arg2)
            {
                double x = 0;
                double y = 0;
                double z = 0;
                if (double.TryParse(arg1, out x) && double.TryParse(arg2, out y))
                {
                    z = x + y;
                    return z.ToString();
                }
                else
                {
                    return "Input Error!";
                }
            }
        }

    2、调用时如此书写

    ObjectDataProvider odp = new ObjectDataProvider();
    //指定使用的类
    odp.ObjectInstance = new Calculator();
    //指定使用的方法
    odp.MethodName = "Add";
    //方法参数应该按顺序添加
    odp.MethodParameters.Add("100");
    odp.MethodParameters.Add("200");
    //odp.Data.ToString() 获得方法返回值
    MessageBox.Show(odp.Data.ToString());

    参考地址:http://msdn.microsoft.com/zh-cn/magazine/cc700358.aspx#id0190082

  • 相关阅读:
    Ubuntu创建用户,给予sudo权限
    Walking Robot Simulation
    python remove与del 的区别
    ML Foundation
    python any()和all()
    python3无穷大,无穷小
    eclipse maven无法下载依赖时
    eclipse自动生成spring项目时各种报错最后处理方案
    Python+Selenium+Unittest实现PO模式web自动化框架(3)
    Python+Selenium+Unittest实现PO模式web自动化框架(2)
  • 原文地址:https://www.cnblogs.com/smallerpig/p/3646218.html
Copyright © 2011-2022 走看看