以下简单数据模板仅在运行时有效。在设计时它什么也不显示。为什么会这样?
<DataTemplate x:Key="SomeEnumDataTemplate">
<ListBox Name="list" Width="20" IsSynchronizedWithCurrentItem="True" SelectedIndex="{Binding Mode=OneWay, Converter={StaticResource EnumToIntConverter}}">
<ListBox.Template>
<ControlTemplate TargetType="ListBox">
<ContentPresenter Content="{TemplateBinding SelectedItem}" />
</ControlTemplate>
</ListBox.Template>
<Rectangle Height="10" Width="10" Fill="Red" />
<Rectangle Height="10" Width="10" Fill="Green" />
<Rectangle Height="10" Width="10" Fill="Yellow" />
</ListBox>
</DataTemplate>
我在另一个 DataTemplate 中像这样使用它:
<HierarchicalDataTemplate x:Key="NodeDataTemplate" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" ToolTip="{Binding Description}">
<ContentControl ContentTemplate="{StaticResource SomeEnumDataTemplate}" Content="{Binding Mode}" Margin="3,0,0,0" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
它再次在具有设计时数据的 UserControl 中使用:
<UserControl x:Class="MyProject.Views.MyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ViewModels="clr-namespace:MyProject.ViewModels" mc:Ignorable="d"
d:DesignHeight="780" d:DesignWidth="400" d:DataContext="{x:Static ViewModels:SampleData.RootNode}">
<TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource NodeDataTemplate}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</UserControl>
最佳答案
您可以轻松创 build 计时数据:
创建您的数据模型:
public class Person { public string Name { get; set; } public int Age { get; set; } } public class PersonCollection : List<Person> { public PersonCollection() { } }
创建一个扩展名为
.xaml
的文件,其中包含:
DesignTimeTreeData.xaml
<local:PersonCollection xmlns:local="clr-namespace:Test_TreeWithDesignData">
<local:Person Name="Joan Solo" Age="32" />
<local:Person Name="Amara Skywalker" Age="31" />
</local:PersonCollection>
- 使用
d:DataContext
和d:DesignData
来使用您在 DesignTimeTreeData.xaml 中指定的数据:
MainWindow.xaml
<Window x:Class="Test_TreeWithDesignData.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test_TreeWithDesignData"
Title="MainWindow"
Height="350"
Width="525"
mc:Ignorable="d">
<Grid>
<TreeView
d:DataContext="{d:DesignData Source=./DesignTimeTreeData.xaml}"
ItemsSource="{Binding}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type local:Person}" >
<StackPanel Orientation="Horizontal" Height="25">
<Label Content="{Binding Name}"/>
<Label Content="{Binding Age}" Margin="3,0,0,0"/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
- 由于
Window.DataContext
属性通常设置为ViewModel
并且TreeView.DataContext
是它的集合,因此,要保持两个数据源都正常工作,您可以用Grid
包围TreeView
,其中DataContext
设置为ViewModel
收藏。
DummyViewModel.cs
public class DummyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public PersonCollection Persons { get; set; }
public DummyViewModel()
{
this.Persons = new PersonCollection();
}
}
MainWindow.xaml
<Window x:Class="Test_TreeWithDesignData.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test_TreeWithDesignData"
Title="MainWindow"
Height="350"
Width="525"
mc:Ignorable="d">
<Window.DataContext>
<local:DummyViewModel />
</Window.DataContext>
<Grid Name="RootGrid">
<Grid Name="TreeGrid" DataContext="{Binding Persons}">
<TreeView d:DataContext="{d:DesignData Source=./DesignTimeTreeData.xaml}"
ItemsSource="{Binding}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type local:Person}" >
<StackPanel Orientation="Horizontal" Height="25">
<Label Content="{Binding Name}"/>
<Label Content="{Binding Age}" Margin="3,0,0,0"/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Grid>
</Window>
结果:
编辑
下一个问题是:如何在设计器中展开项目?
Person
将拥有一个人员集合:public class Person { public string Name { get; set; } public int Age { get; set; } public PersonCollection Childs { get; set; } }
设计时数据将有一个子数据
DesignTimeTreeData.xaml
<local:PersonCollection xmlns:local="clr-namespace:Test_TreeWithDesignData">
<local:Person Name="Joan Solo" Age="32" />
<local:Person Name="Amara Skywalker" Age="31">
<local:Person.Childs>
<local:PersonCollection>
<local:Person Name="Han Skywalker" Age="10" />
</local:PersonCollection>
</local:Person.Childs>
</local:Person>
</local:PersonCollection>
树现在将有一个 HierarchicalDataTemplate:
<HierarchicalDataTemplate DataType="{x:Type local:Person}" ItemsSource="{Binding Childs}"> <StackPanel Orientation="Horizontal" Height="25"> <Label Content="{Binding Name}"/> <Label Content="{Binding Age}" Margin="3,0,0,0"/> </StackPanel> </HierarchicalDataTemplate>
并且
TreeView
将绑定(bind)到DesignerProperties.IsInDesignMode
以展开设计器中的项目:<TreeView.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(pf:DesignerProperties.IsInDesignMode)}" Value="true" > <Setter Property="IsExpanded" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle>
这是窗口的 xaml:
MainWindow.xaml
<Window x:Class="Test_TreeWithDesignData.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test_TreeWithDesignData"
xmlns:pf="clr-namespace:System.ComponentModel;assembly=PresentationFramework"
Title="MainWindow"
Height="250"
Width="325"
mc:Ignorable="d"
>
<Window.DataContext>
<local:DummyViewModel />
</Window.DataContext>
<Grid Name="RootGrid">
<Grid Name="TreeGrid" DataContext="{Binding Persons}">
<TreeView
d:DataContext="{d:DesignData Source=./DesignTimeTreeData.xaml}"
ItemsSource="{Binding}"
>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Self}, Path=(pf:DesignerProperties.IsInDesignMode)}"
Value="true"
>
<Setter Property="IsExpanded" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate
DataType="{x:Type local:Person}"
ItemsSource="{Binding Childs}"
>
<StackPanel Orientation="Horizontal" Height="25">
<Label Content="{Binding Name}"/>
<Label Content="{Binding Age}" Margin="3,0,0,0"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Grid>
</Window>
这就是结果:
关于wpf - 为什么这个数据模板在设计时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4224332/