如何使gridview成为wpf应用程序中树视图的子元素 [英] How to make gridview a child element of a treeview in wpf application

查看:99
本文介绍了如何使gridview成为wpf应用程序中树视图的子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从数据库中填充一个数据网格(或gridview)作为树视图的子项。我可以从树中的数据库获取数据,但是它似乎不适用于数据网格。这是我的xaml代码:

I am trying to populate a datagrid (or gridview) as a child elment of a treeview from the database. I am able to get data from the DB in the tree, however, it doesnt seem to work for the datagrid. Here is my xaml code:

<Window x:Class="AttemptUsingHirarchichalData.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:data="clr-namespace:AttemptUsingHirarchichalData"
    xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1" Height="300" Width="300">
<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type data:Root}"
                              ItemsSource="{Binding Path=RootList}">
        <TextBlock Text="{Binding RootNode}"/>

    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type data:Nodes}"
                              ItemsSource="{Binding Path=ChildList}">

        <TextBlock Text="{Binding ChildNode}"/>
    </HierarchicalDataTemplate>
</Window.Resources>

<Grid>
    <TreeView Name="TreeView1">
        <TreeViewItem ItemsSource="{Binding Path=RootList}"
                      Header="{Binding RootNode}"/>
        <TreeViewItem ItemsSource="{Binding Path=dt_Age}"
                      Header="{Binding dt_Age}"/>
    </TreeView>

</Grid>

我的codebehind是这样的:

My codebehind is something like this:

InitializeComponent();

Root obj_Root = new Root();
obj_Root.RootNode = "RootNode";
obj_Root.RootList = new List<Nodes>();

Class1 obj_Class1 = new Class1();
DataTable dt_Age = obj_Class1.GetAgeInComboBox();

for (int i = 0; i < dt_Age.Rows.Count; i++)
{
    Nodes obj_AgeNode = new Nodes();
    obj_AgeNode.ChildNode = dt_Age.Rows[i][0].ToString();
    obj_Root.RootList.Add(obj_AgeNode);

    Class1 obj_class = new Class1();
    DataTable dt_name = new DataTable();
    dt_name = obj_class.GetName(Convert.ToInt32(dt_Age.Rows[i][0]));
    obj_AgeNode.ChildList = new List<Nodes>();
    //gridv
    for (int j = 0; j < dt_name.Rows.Count; j++)
    {
        Nodes obj_NameNode = new Nodes();
        obj_NameNode.ChildNode = dt_name.Rows[j][0].ToString();
        obj_AgeNode.ChildList.Add(obj_NameNode);
    }
}

TreeView1.DataContext = obj_Root;

我的类文件作为其中的一部分:

My Class file has this as a part of it:

public class Nodes
{
    public string ChildNode { get; set; }
    public List<Nodes> ChildList { get; set; }
}

public class Root
{
    public string RootNode { get; set; }
    public List<Nodes> RootList { get; set; }
}

 public DataTable GetAgeInComboBox()
 {
     SqlDataAdapter da_Age = new SqlDataAdapter("select distinct Age from myfrstattemt", conn1);
     DataTable dt_Age = new DataTable();
     da_Age.Fill(dt_Age);
     return dt_Age;
 }

请告诉我如何实现它。我是新的,所以请原谅我的愚蠢的错误,请尝试简单的解释。谢谢。

Please tell me how to implement it. I am new to this, so please excuse my stupid errors, and please try to explain in simple terms. Thank you.

这是我实际需要做的

http://i31.tinypic.com/21q44p.png

推荐答案

好消息是,您在这里做的工作比您需要的更多,这可能是您遇到麻烦的原因。

The good news is that you're doing a lot more work here than you need to, which is probably why you're having trouble.

坏消息是,您应该更多地学习一些关于WPF的内容,以便正确地了解WPF,并提出一个干净简洁的好方法。我会尝试指向正确的方向。

The bad news is that you should really study a little more about WPF to properly grok this and come up with a good approach that's clean and concise. I'll try and point you in the right direction.

首先,你应该围绕ItemsControl。这是一个非常强大的类,是WPF应用程序中许多日常控件的基础类。您应该了解如何将任何集合(IEnumerable,IList,IBindingList等)绑定到ItemsControl的ItemsSource属性将导致创建子项。

Firstly, you should get your head around ItemsControl. It's a really powerful class and is the base class of many of the everyday controls you would use in a WPF application. You should understand how binding any collection (IEnumerable, IList, IBindingList etc) to the ItemsSource property of ItemsControl will cause child items to be created.

您应该明白(if您还没有)通过DataTemplates将数据类型转换为UI元素。这是一个简单而强大的概念。

You should then understand (if you don't already) how data types are converted into UI elements via DataTemplates. This is a simple but powerful concept.

然后,您应该尝试使用上述的一个小扩展,即HeaderedItemsControl和HierarchicalDataTemplate。这将为您提供使用TreeView所需的所有工具。

Then you should experiment with a small extension to the above, namely HeaderedItemsControl and HierarchicalDataTemplate. This will give you all the tools you need to use the TreeView in the way you want to.

您无需在C#代码中创建任何TreeViewItem。如果您可以获得底层数据对象以反映要显示的层次结构(无论每个节点是否是简单文本标签还是数据网格),那么您可以为所有级别创建分层数据模板,并且WPF会对所有层次进行绑定并为您创建TreeViewItem。

At no point would you need to create any TreeViewItems in C# code. If you can get the underlying data objects to reflect the hierarchy you want to display (irrespective of whether each node is a simple text label or a data grid) then you can create hierarchical data templates for all levels and have WPF take care of binding everything and creating the TreeViewItems for you.

编辑

我有一些问题您编辑过的问题:

I have some questions for your edited question:


  1. Root 节点

  2. 你有一个类层次结构来模拟节点之间的关系吗?如果是这样,只是使用它而不是将对象复制到节点的实例中。我会给你一个例子。

  1. What is the difference between Root and Nodes?
  2. Do you have a class hierarchy that models the relationship between nodes? If so, just use that rather than copying the objects into instances of Root and Nodes. I'll give you a made up example.

我们假设你有客户 订单 s,每个订单都有项目 s。

Let's assume you have Customers who place Orders, and each order has Items.

public class Customer
{
    public string Name { get; set; }
    public IEnumerable<Order> Orders { get; set; }
}

public class Order
{
    public DateTime PurchaseDate { get; set; }
    public IEnumerable<OrderItem> Items { get; set; }
}

public class OrderItem
{
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public double UnitPrice { get; set; }
    public double TotalPrice { get; set; }
}

上述类型代表层次结构。如果你有这样的结构,那么你可以直接绑定到UI。您不需要创建任何 Node 对象。这是WPF方式:)

The above types represent a hierarchy. If you have a structure like this, then you can bind it directly to the UI. You don't need to create any Root or Node objects. This is the WPF way :)

(请注意,如果您没有上述类层次结构,则可以设置专门为在UI中创建的类。更多关于MVVM模式,如果你有兴趣。)

(Note that if you don't have the above class hierarchy, you might set about creating one specifically for use in the UI. Read more about the MVVM pattern if you're interested.)

在你的XAML中,你将定义TreeView为:

In your XAML you would define the TreeView as:

<TreeView x:Name="_treeView" ItemsSource="{Binding}">
  <TreeView.Resources>
    <HierarchicalDataTemplate DataType="{x:Type data:Customer}"
                              ItemsSource="{Binding Path=Orders}">
      <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
    <DataTemplate DataType="{x:Type data:Order}">
      <StackPanel>
        <TextBlock Text="{Binding PurchaseDate}"/>
        <ListView ItemsSource="{Binding Items}">
          <ListView.View>
            <GridView>
              <GridViewColumn DisplayMemberBinding="{Binding ProductName}" />
              <GridViewColumn DisplayMemberBinding="{Binding Quantity}" />
              <GridViewColumn DisplayMemberBinding="{Binding UnitPrice}" />
              <GridViewColumn DisplayMemberBinding="{Binding TotalPrice}" />
            </GridView>
          </ListView.View>
        </ListView>
      </StackPanel>
    </DataTemplate>
  </TreeView.Resources>
</TreeView>

在代码隐藏中,您可以这样做:

And in code-behind, you'd do something like this:

 _treeView.DataContext = customers; // eg. IEnumerable<Customer>

这篇关于如何使gridview成为wpf应用程序中树视图的子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆