简体   繁体   中英

WPF One Treeview and different HierarchicalDataTemplate in it

I want TreeView

Books that can be Programming, Cooking, Other. Discs that can be CD or DVD. Books and Disc have Good_type_id.There must be strucrure like in database I created.

Book
  Programming
  Cooking
  Other
Disc
  CD 
  DVD

There would be another type of discs and some extra params for books but not in this topic. My result is

Book
  Programming
  Cooking
  Other
Disc

I want HierarchicalDataTemplate not only for book type but for disc type. I do not know how to do it in one treevie. Here is code. In treeview would be some nested items or join sql code but not in this topic. I create 2 relations. One for books through [Good_Type_Id] works. I wanna the same for discs in one treeview.

CREATE TABLE [dbo].[Book_type] (
[Good_Type_Id] [varchar] (50) NOT NULL,
[Book_Type_Id] [varchar] (50) NOT NULL,
[Book_Type_Name] [varchar] (50) NOT NULL,
) ON [PRIMARY]
GO

INSERT INTO [dbo].[Book_type] VALUES  ('1','1b','Programming');
INSERT INTO [dbo].[Book_type] VALUES  ('1','2b','Cooking');
INSERT INTO [dbo].[Book_type] VALUES  ('1','3b','Other_Book');


CREATE TABLE [dbo].[Disc_type] (
[Good_Type_Id] [varchar] (50) NOT NULL,
[Disc_Type_Id] [varchar] (50) NOT NULL,
[Disc_Type_Name] [varchar] (50) NOT NULL,
) ON [PRIMARY]
GO

INSERT INTO [dbo].[Disc_type] VALUES  ('2','1d','CD');
INSERT INTO [dbo].[Disc_type] VALUES  ('2','2d','DVD');



namespace Test
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            try
            {
                this.GoodTreeView.DataContext = Test.CreateDataRelation();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message); 
            }
        }
    }
}
    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace Test
{
    public static class Test
    {
        #region

        /// <summary>
        /// Data Relation Between Two Tables Such as good_type and Goods
        /// </summary>
        /// <returns>DataSet</returns>
        public static DataSet CreateDataRelation()
        {
            try
            {
                SqlConnection SqlCon = new SqlConnection();
                SqlCon.ConnectionString = @"Data Source=(local);DATABASE=Test;Integrated Security=SSPI";
                SqlCon.Open();

                //SqlDataAdapter Sql_Good_Type_Da = new SqlDataAdapter("SELECT Good_Type_Id,Good_Type_Name from Good_Type", SqlCon);
                SqlDataAdapter Sql_Good_Type_Da = new SqlDataAdapter("SELECT * from Good_Type", SqlCon);
                //SqlDataAdapter Sql_Book_Type_Da = new SqlDataAdapter("SELECT Good_type_Id, Book_Type_Id, Book_type_Name from Book_type", SqlCon);
                SqlDataAdapter Sql_Book_Type_Da = new SqlDataAdapter("SELECT * FROM Book_type", SqlCon);
                SqlDataAdapter Sql_Disc_Type_Da = new SqlDataAdapter("SELECT * FROM Disc_type", SqlCon);
                DataSet Ds = new DataSet();
                Sql_Good_Type_Da.Fill(Ds, "Good_Type");
                Sql_Book_Type_Da.Fill(Ds, "Book_Type");
                Sql_Disc_Type_Da.Fill(Ds, "Disc_Type");


                DataRelation Dr_Good_Book = new DataRelation
                    ("Good_Book_Relation",
                    Ds.Tables["Good_Type"].Columns["Good_Type_Id"],
                    Ds.Tables["Book_Type"].Columns["Good_Type_Id"],
                    true
                    );

                DataRelation Dr_Good_Disc = new DataRelation
                    ("Good_Disc_Relation",
                    Ds.Tables["Good_Type"].Columns["Good_Type_Id"],
                    Ds.Tables["Disc_Type"].Columns["Good_Type_Id"],
                    true
                    );


                Dr_Good_Book.Nested = true;
                Dr_Good_Disc.Nested = true;

                Ds.Relations.Add(Dr_Good_Book);
                Ds.Relations.Add(Dr_Good_Disc);

                return Ds;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        #endregion
    }
}

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="Book_Type_DataTemplate">
            <Grid Width="800" Height="20">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.771*"/>
                    <ColumnDefinition Width="0.229*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.5*"/>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Good_Type_Id}" Margin="0,0" Foreground="Black"></TextBlock>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Book_Type_Id}" Margin="100,0" Foreground="Black"></TextBlock>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Book_Type_Name}" Margin="200,0" Foreground="Black"></TextBlock>             
            </Grid>              
        </DataTemplate>

        <DataTemplate x:Key="Disc_Type_DataTemplate">
            <Grid Width="800" Height="20">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.771*"/>
                    <ColumnDefinition Width="0.229*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.5*"/>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Good_Type_Id}" Margin="0,0" Foreground="Black"></TextBlock>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Disc_Type_Id}" Margin="100,0" Foreground="Black"></TextBlock>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Disc_Type_Name}" Margin="200,0" Foreground="Black"></TextBlock>
            </Grid>
        </DataTemplate>


        <HierarchicalDataTemplate x:Key="Good_Book_DataTemplate" 
                      ItemsSource="{Binding Good_Book_Relation}" 
                      ItemTemplate="{StaticResource Book_Type_DataTemplate}">       
            <Grid Height="20">
                <TextBlock Text="{Binding Good_Type_Name}" Margin="10,0" HorizontalAlignment="Stretch" VerticalAlignment="Center"></TextBlock>    
                </Grid>     
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate x:Key="Good_Disc_DataTemplate" 
                      ItemsSource="{Binding Good_Disc_Relation}" 
                      ItemTemplate="{StaticResource Disc_Type_DataTemplate}">
            <Grid Height="20">
                <TextBlock Text="{Binding Good_Type_Name}" Margin="10,0" HorizontalAlignment="Stretch" VerticalAlignment="Center"></TextBlock>
            </Grid>
        </HierarchicalDataTemplate>


    </Window.Resources>
    <Grid>

        <TreeView x:Name="GoodTreeView" ItemsSource="{Binding Good_Type}" ItemTemplate="{DynamicResource Good_Book_DataTemplate}" 
                  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">          
        </TreeView>


    </Grid>
</Window>

I think you are coupling your data objects and your view objects far too closely together. have a look at the MVVM pattern.

At the moment you have models that come back from the data access calls, and you are binding your view directly onto them. You need to introduce something to translate between the two tiers. In this way you can have DiscViewModel s and BookViewModel s and have different data templates for each.

You might even want to define

class BookViewModel : BaseViewModel {}
class DiscViewModel : BaseViewModel {}

class BaseViewModel
{
  // All properties defined here
}

as the WPF type engine will still distinguish between the two classes even if they are identical.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM