我在尝试对齐分布在多个数据模板中的内容时遇到了问题。
我正在构建一个灵活的Forms框架,它基本上允许我们在数据库中输入元数据,从这个元数据中水合模型并将这些模型的集合绑定到View。然后,View使用模板选择器根据模型元数据选择要显示到视图的相应UI元素。
例如,以下数据模板是我正在使用的几个:
<DataTemplate DataType="{x:Type models:FormField}"
x:Key="TextBoxDataTemplate">
<WrapPanel Margin="5 5 5 0">
<TextBlock Text="{Binding Path=Description}"
Margin="0 0 10 0"
HorizontalAlignment="Right"/>
<formViews:TextInputUserControl />
</WrapPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type models:FormField}"
x:Key="MultiLineTextBoxDataTemplate">
<WrapPanel Margin="5 5 5 0">
<TextBlock Text="{Binding Path=Description}"
HorizontalAlignment="Right"
Margin="0 0 10 0" />
<formViews:MultiLineTextInputUserControl HorizontalAlignment="Left"
MinWidth="250"
MinHeight="100"/>
</WrapPanel>
</DataTemplate>
用户控件只不过是关联视图模型的文本框数据绑定,以及代码隐藏中发生的一些小问题。
当他们渲染到屏幕时,TextBlock
宽度会导致关闭。
Description _________
User name ________
Employee Identification ______
etc.
可以将视图切片到各个部分。每个部分都是一个DockPanel,它包含一个ItemsControl,绑定到为每个部分指定的元数据对象集合。
------------------------------------
Header
------------------------------------
| | | |
| | | |
| | | |
|Left | Body |Right |
| | | |
| | | |
------------------------------------
Footer
------------------------------------
我们尝试了几种解决方案。
我们使用WrapPanel
代替Grid
。 TextBlock放在第0列,用户控件放在第1列。这样可行,但我们必须为第1列中的所有元素提供最小宽度。复选框必须保持与文本框相同的宽度,这看起来并不好。如果我们没有指定最小宽度,则文本框的宽度变为15pt。
我们尝试了各种配置中的Grid列,包括共享大小组。允许不同的元素类型具有不同的宽度会导致布局问题。
另一个问题是,当视图缩小时,我们失去了元素的良好包装。如果某个部分中的ItemsControl
未包含任何项目,则停靠面板会折叠。我们想要使用包装面板,以便内容从右向左流动并填充所需的空间。如果右侧部分有物品,则身体会收缩并垂直流动。
这是通过将itemscontrol面板更改为包装面板,并使数据模板中的根容器成为包装面板来实现的。除了对齐问题外,这种方法效果很好。
我们在Windows视图模型中创建了一个DisplayTextWidth属性。由于Forms框架是通用的,我们有几个Windows&amp;以不同的方式使用此框架查看模型。我们将视图模型隐藏在需要DisplayTextWidth的接口后面,然后使用相对路径将每个TextBlock的宽度绑定到它。
public double DisplayTextWidth
{
get
{
return this.displayTextWidth;
}
set
{
if (value > this.displayTextWidth)
{
this.displayTextWidth = value;
this.OnPropertyChanged();
}
}
}
问题是该属性始终为零,并且setter从未被击中。即使绑定设置为双向。
在我的代码中,我将TextBlocks宽度绑定到视图中最宽的textblock元素:
<Label Content="Category:"
Width="{Binding ActualWidth, ElementName=ContractorLabel}"
VerticalAlignment="Center"
HorizontalContentAlignment="Right" />
<ComboBox x:Name="CategoryComboBox"
MinWidth="200"
ItemsSource="{Binding EquipmentFilter.EquipmentCategories}"
SelectedItem="{Binding EquipmentFilter.SelectedEquipmentCategory}"
Margin="10 0 0 0"
DisplayMemberPath="Name">
这很有效,给我的结果如下:
Employee _________
Age _________
Title _________
虽然没有一点工作,但我无法使用数据模板。我想知道是否应该编写一个依赖属性来遍历可视化树并将TextBlock宽度设置为相同的所有宽度,其中w / e TextBlock的宽度最宽。我可以使用标签装饰数据模板中的TextBlocks,然后查找标签,然后将宽度分配给每个TextBlock以匹配最宽的。
这看起来有点矫枉过正,还有另外一条路可以采取这个措施吗?