我有一些关于TreeView的分层模板格式化的问题。这张图片将说明:
以下是第三级的XAML代码:
<HierarchicalDataTemplate
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ItemsSource="{Binding XPath=Unit}"
>
<Grid Height="42" Width="auto" >
<Grid Height="41" HorizontalAlignment="Left" Margin="0,0,0,0" Name="grid1" VerticalAlignment="Top" Width="auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Image Source= "{Binding XPath=UnitIcon}" Grid.Column="1" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Left" Stretch="None" OpacityMask="White"></Image>
<Label Content="{Binding XPath=UnitName}" Height="54" HorizontalAlignment="Left" Name="label4" VerticalAlignment="Top" FontFamily="Smythe" FontSize="18" Margin="0,0,0,0" Grid.RowSpan="3" Grid.Column="2" Grid.ColumnSpan="3"/>
<Label Content="Strength:" FontFamily="Amaltea WF" FontSize="12" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Center" Grid.Column="2" Grid.Row="2"/>
<TextBlock Text="{Binding XPath=UnitStrength, ConverterParameter=N0}" Margin="0,0,0,0" FontFamily="BauderieScriptSSK Bold" FontSize="18" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="3" Grid.Row="2"/>
</Grid>
<Line X1='0'
X2='200'
Y1='0'
Y2='0'
Stroke="Gray"
StrokeThickness='1' />
</Grid>
</HierarchicalDataTemplate>
提前感谢您的帮助!
答案 0 :(得分:1)
从UnitName标签上取下固定高度。你有网格单元,你不想要固定的高度。部分差距可能是字体的行高。暂时在标签上设置Background="LightSkyBlue"
以查看标签本身实际占用的空间大小。
图片上的VerticalAlignment="Center"
看起来并没有达到预期的效果,因为您已经在所有内容上设置了相互冲突的固定高度。您的grid1
固定为41个单位高,但其中的单位名称高54个单位。布局引擎正在尽最大努力遵守您提供的相互矛盾的订单。
删除XAML中的每个固定高度。每一个,没有例外。让事情变得自己。如果绝对必须在控件上施加固定高度,请考虑将其内容放在ViewBox
中,这样内容可以自动调整大小而不会溢出容器。或不;这可能看起来很奇怪。但首先让你的相对布局工作,然后开始把它塞进你已经得到的任何有限的空间。
当您在使用XAML布局时出现问题时,天真的冲动就是添加内容。最糟糕的是,添加随机的东西 - &#34;我不知道这个属性意味着什么或它的价值意味着什么,但也许如果我将它添加到这个控件上,它& #39;解决另一个错误的问题!&#34; - 在最佳,你添加的东西将是无害的。
不要这样做。 删除内容,然后重新构建。 一次添加一件事,看看它的作用。并且在没有先阅读文档的情况下添加 nothing 。从Intellisense 添加六个随机属性似乎比在MSDN上查找一个属性花费的时间更少,但实际情况并非如此,因为第一种方法始终保证完全浪费时间这就像是闭上眼睛驾驶,试图通过撞到障碍物的感觉来驾驶。您正在将正确的格式字符串分配给错误的属性。试试这个:
<TextBlock Text="{Binding XPath=UnitStrength, StringFormat=N0}"
除了哎呀哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈这也不是:
Binding.XPath
我怀疑他们失败了,因为你给他们一个字符串而不是一个整数,但这只是一个猜测。
但这很有效。
<Label Content="{Binding XPath=UnitStrength}" ContentStringFormat="N0" />
XAML。 public class IntToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int n = 0;
if (Int32.TryParse((string)value, out n))
{
value = n.ToString((String)parameter);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
是您定义YOUR_NAMESPACE_HERE
类的C#命名空间。那不一定非必要;它可以位于此XAML文件中的父标记或任何包含标记上,包括根标记(IntToStringConverter
或Window
或UserControl
)。把它放在这里使得这个例子更加独立。
ResourceDictionary
<HierarchicalDataTemplate
xmlns:local="clr-namespace:YOUR_NAMESPACE_HERE"
>
<HierarchicalDataTemplate.Resources>
<local:IntToStringConverter
x:Key="IntToString"
/>
</HierarchicalDataTemplate.Resources>
<!-- blah blah -->
<TextBlock
Text="{Binding XPath=UnitStrength, Converter={StaticResource IntToString}, ConverterParameter=N0}"
/>
对于TreeView:
<Window.Resources>
<!-- stuff -->
<HierarchicalDataTemplate
x:Key="UnitTemplate"
ItemsSource="{Binding XPath=Unit}"
>
<Grid Width="auto">
<!-- stuff -->
</Grid>
</HierarchicalDataTemplate>
<!-- stuff -->
</Window.Resources>
但是,如果模板只在一个地方使用,那么这也有效:
<TreeView
...
ItemTemplate="{StaticResource UnitTemplate}"
...
/>
或者最后,如果您想将所有数据模板放在自己的文件中,您需要创建资源字典:
<TreeView
...
>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate
ItemsSource="{Binding XPath=Unit}"
>
<Grid Width="auto">
<!-- stuff -->
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
DataTemplate.xaml
<Window.Resources>
<!-- If you're doing the merged thing, you have to explicitly have the
ResourceDictionary tag here.
-->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DataTemplates.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- other resources maybe -->
</ResourceDictionary>
</Window.Resources>
因此,我们正在查看的树有多个级别,每个级别都有不同的模板。有两种方法可以做到这一点,至少:如果我们有一个具有不同子类型的.NET类树,我们可以定义&#34;隐式模板&#34;在资源字典中。他们拥有<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ScenarioEditor"
>
<local:IntToStringConverter
x:Key="IntToString"
/>
<HierarchicalDataTemplate
x:Key="UnitTemplate"
ItemsSource="{Binding XPath=Unit}"
>
<Grid Width="auto">
<!-- stuff -->
</Grid>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate
x:Key="SomeOtherTemplate"
>
<Grid Width="auto">
<!-- different stuff -->
</Grid>
</HierarchicalDataTemplate>
</ResourceDictionary>
属性而不是DataType
,结果是(例如)带有x:Key
的模板会自动用于显示该类型的任何类实例。
但是您已经获得了XML,因此无法运行。您可以做的是为每个DataType="{x:Type local:HQ}"
提供自己的HierarchicalDataTemplate
。为清楚起见,以下示例省略了ItemTemplate
以及其他许多内容 - 它仅说明了我们如何设置这些父/子模板关系。
ItemsSource
<HierarchicalDataTemplate
x:Key="UnitTemplate"
>
<Grid>
<!-- Unit stuff -->
</Grid>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate
x:Key="CommanderTemplate"
ItemTemplate="{StaticResource UnitTemplate}"
>
<Grid>
<!-- Commander stuff -->
</Grid>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate
x:Key="HQTemplate"
ItemTemplate="{StaticResource CommanderTemplate}"
>
<Grid>
<!-- HQ stuff -->
</Grid>
</HierarchicalDataTemplate>
将是树视图的HQTemplate
ItemTemplate