How can I implement this weird WPF TreeListDataGridView?

As you can see in the image below, I have a datamodel tree made up of groups that can contain other groups plus an arbined number of items that can contain parameters again. The parameters themselves are defined globally and are simply repeated in the elements. Only the actual value of the parameter may differ from using the parameter to use the parameters in different elements.

The image below is a typical WPF TreeView control with a custom control template and datatemplates for the items.

Now my goal is to remove the parameter names above the textboxes and place them vertically in a separate column at the very left corner of the treeview and just leave the textboxes there, and also stack vertically to match their parameter names in the first column.

Is there a way to solve this problem with control templates and data templates and data binding to the view model? (Yes, I am using MVVM)

tree image http://img242.imageshack.us/img242/5377/treebh8.th.png image link

The problem is a general layout issue that should work well with data binding. I usually want to bind an object graph to a view that looks somewhat like this (cutout layout):

treelayout http://img75.imageshack.us/img75/5763/treelayoutjh5.jpg

Please note that ParamX headers are no longer part of the treelayout. But the values ​​are still there. The values ​​should now communicate (i.e. are on the same line) with them. Also, if none of the elements in the tree contain, for example, Param1, the Param1 header and the corresponding line should disappear completely.

0


source to share


2 answers


I am not an expert on tree structure, but it is easy to build something like this without a tree view.

Start with a blank VS2008 Wpf app named WpfTreeGridWhatever

First, let's define our model:

using System;
using System.Collections.Generic;

namespace WpfTreeGridWhatever
{
    public class ItemBase
    {
    }
    public class Group : ItemBase
    {
        public string Name { get; set; }
        public IList<ItemBase> Items { get; set; }
    }
    public class Item : ItemBase
    {
        public string Name { get; set; }
        public IList<Parameter> Parameters { get; set; }
    }
    public class Parameter
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }
}

      

now, in the constructor Window1 create our objects (we just have some data to bind):



   public Window1()
    {
        DataContext = new Group[]
        {
            new Group()
            {
                Name="Group A",
                Items = new List<ItemBase>()
                {
                    new Item()
                    {
                        Name="Item",
                        Parameters=new List<Parameter>()
                        {
                            new Parameter(){Name="Param 1",Value="12"},
                            new Parameter(){Name="Param 2",Value="true"},
                            new Parameter(){Name="Param 3",Value="0.0"},
                            new Parameter(){Name="Param 4",Value="off"},
                        }
                    },
                    new Item()
                    {
                        Name="Item",
                        Parameters=new List<Parameter>()
                        {
                            new Parameter(){Name="Param 1",Value="12"},
                            new Parameter(){Name="Param 2",Value="true"}
                        }
                    },
                    new Group()
                    {
                        Name="Group B",
                        Items = new List<ItemBase>()
                        {
                            new Item()
                            {
                                Name="Item",
                                Parameters=new List<Parameter>()
                                {
                                    new Parameter(){Name="Param 1",Value="12"},
                                    new Parameter(){Name="Param 2",Value="true"},
                                    new Parameter(){Name="Param 3",Value="0.0"},
                                    new Parameter(){Name="Param 4",Value="off"},
                                }
                            },
                            new Item()
                            {
                                Name="Item",
                                Parameters=new List<Parameter>()
                                {
                                    new Parameter(){Name="Param 1",Value="12"},
                                    new Parameter(){Name="Param 2",Value="true"},
                                    new Parameter(){Name="Param 3",Value="0.0"},
                                    new Parameter(){Name="Param 4",Value="off"},
                                    new Parameter(){Name="Param 5",Value="2000"},
                                }
                            },
                            new Item()
                            {
                                Name="Item",
                                Parameters=new List<Parameter>()
                                {
                                    new Parameter(){Name="Param 1",Value="12"},
                                    new Parameter(){Name="Param 2",Value="true"},
                                }
                            },
                            new Group()
                            {
                                Name="Group C",
                                Items = new List<ItemBase>()
                                {
                                    new Item()
                                    {
                                        Name="Item",
                                        Parameters=new List<Parameter>()
                                        {
                                            new Parameter(){Name="Param 1",Value="12"},
                                            new Parameter(){Name="Param 2",Value="true"},
                                            new Parameter(){Name="Param 3",Value="0.0"},
                                            new Parameter(){Name="Param 4",Value="off"},
                                        }
                                    },
                                    new Item()
                                    {
                                        Name="Item",
                                        Parameters=new List<Parameter>()
                                        {
                                            new Parameter(){Name="Param 1",Value="12"},
                                            new Parameter(){Name="Param 2",Value="true"},
                                            new Parameter(){Name="Param 3",Value="0.0"},
                                            new Parameter(){Name="Param 4",Value="off"},
                                            new Parameter(){Name="Param 5",Value="2000"},
                                        }
                                    },
                                    new Item()
                                    {
                                        Name="Item",
                                        Parameters=new List<Parameter>()
                                        {
                                            new Parameter(){Name="Param 1",Value="12"},
                                            new Parameter(){Name="Param 2",Value="true"},
                                        }
                                    },
                                }
                            }
                        }
                    }
                }
            }
        };

        InitializeComponent();
    }

      

And now, magic - use this code in Window1.xaml

<Window x:Class="WpfTreeGridWhatever.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:WpfTreeGridWhatever"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <LinearGradientBrush x:Key="Bk" StartPoint="0,0" EndPoint="0,1" >
            <GradientStop Offset="0" Color="DarkGray"/>
            <GradientStop Offset="1" Color="White"/>
        </LinearGradientBrush>
        <DataTemplate DataType="{x:Type l:Parameter}">
            <Border CornerRadius="5" Background="{StaticResource Bk}"
                    BorderThickness="1" BorderBrush="Gray" Margin="2" >
                <StackPanel Margin="5">
                    <TextBlock Height="12" Text="{Binding Name}"/>
                    <TextBox Height="22" Text="{Binding Value}"/>
                </StackPanel>
            </Border>
        </DataTemplate>
        <DataTemplate DataType="{x:Type l:Item}" >
            <StackPanel>
                <Border CornerRadius="5" Background="{StaticResource Bk}"
                    BorderThickness="1" BorderBrush="Gray" Height="25" Margin="3">
                    <TextBlock Height="12" Text="{Binding Name}" VerticalAlignment="Center" Margin="3,0"/>
                </Border>
                <ItemsControl ItemsSource="{Binding Parameters}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
        <DataTemplate DataType="{x:Type l:Group}">
            <StackPanel>
                <Border CornerRadius="5" Background="{StaticResource Bk}"
                    BorderThickness="1" BorderBrush="Gray" Height="25" Margin="3">
                    <TextBlock Height="12" Text="{Binding Name}" VerticalAlignment="Center" Margin="3,0"/>
                </Border>
                <ItemsControl ItemsSource="{Binding Items}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>

    </Window.Resources>
    <Grid>
        <ItemsControl ItemsSource="{Binding}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>
</Window>

      

It should start.

+1


source


You can only try what you suggest in the title of the question - create a TreeListDataGridView. It will be a custom control consisting of a TreeView for the top and a DataGrid for the bottom - or maybe just a regular Grid, depending on the effect you want. This way you get your look and feel and you retain all the benefits of data binding, control templates, etc.



0


source







All Articles