如下图所示,我有一个树状数据模型,其中包含可以包含其他组的组以及可以再次容纳参数的任意数量的项目。参数本身是全局定义的,只是在项目中重复出现。只有参数的实际值可能与参数使用情况不同,不同项目中的参数使用情况不同。
下图是一个普通的WPF树视图控件,带有自定义控件模板和项目的数据窗口。
现在我的目标是删除文本框上方的参数名称,并将它们垂直堆叠在树视图的最左侧的单独列中,只需将文本框保留在那里,但也垂直堆叠,以便它们与其中的参数名称相对应。第一栏。
有没有办法可以通过控件模板和数据模板以及数据绑定到视图模型来解决这个问题? (是的,我使用MVVM)
treeview image http://img242.imageshack.us/img242/5377/treebh8.th.png image link
问题是一般的布局问题,必须与数据绑定一起使用。通常我想将对象图绑定到一个看起来像这样的视图(剪切模型):
treelayout http://img75.imageshack.us/img75/5763/treelayoutjh5.jpg
请注意,ParamX标头不再是treelayout的一部分。但价值仍然存在。现在,值必须与它们保持连接(即,它们在同一行上)。此外,如果树中没有任何项目包含例如Param1,则Param1标题和相应的行必须完全消失。
答案 0 :(得分:1)
我不是树视图专家,但是在没有树视图的情况下构建类似的东西很容易。
从名为WpfTreeGridWhatever
的空VS2008 Wpf应用程序开始首先,让我们定义我们的模型:
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; }
}
}
现在,在Window1构造函数中创建我们的对象(只是为了让我们有一些数据要绑定):
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();
}
现在,神奇 - 在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>
这应该让你入门
答案 1 :(得分:0)
您可以尝试在问题标题中设想的内容 - 创建TreeListDataGridView。它将是一个自定义控件,由顶部的TreeView和底部的DataGrid组成 - 或者可能只是一个普通的Grid,具体取决于所需的效果。这样你就会有你的外观和感觉,你将保留数据绑定,控制模板等的所有优点。