[英]How can I use a parent content control from a sub binding?
我目前有以下代码:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}">
</ItemsControl>
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Name="Left" Grid.Row="0" Grid.Column="0" Content="{Binding Label}"/>
<TextBox Name="Right" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" Text="{Binding Value}"/>
</Grid>
</DataTemplate>
绑定到SectionViewModel ItemsControl的ViewModels属性是StringViewModel的列表。 我想将每个StringViewModel插入ItemsControl中的某种内容控件中。 目前,我只有每个StringViewModel都可以创建自己的Grid,但是这使事情变得无法对齐。 我想将这些项目插入ItemsControl中的某种内容控件中,它不一定必须是网格,但它应该在ItemsControl中。 我怎样才能做到这一点? 我也正在使用MVVM Light跟踪MVVM。
编辑:我修改了XAML,以反映当前如何设置它。
如果要控制包含模板中的宽度,可以使用继承的附加属性:
public class WidthInformation
{
// Use propa snippet to create LabelWidth property with this metadata:
... RegisterAttached("LabelWidth", typeof(double), typeof(WidthInformation), new FrameworkPropertyMetadata
{
Inherits = true
});
}
因此,它将被使用:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}"
local:WidthInformation.LabelWidth="60" />
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}"
Width="{Binding Path=(local:WidthInformation.LabelWidth)"/>
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
使用DockPanel将导致TextBox宽度自动填充剩余的空间。
另一方面,如果希望两列相对于彼此具有相同的百分比大小,则可以在列上使用星号大小:
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Label}" />
<TextBox Text="{Binding Value}" Grid.Column="1" />
</DockPanel>
</DataTemplate>
一个非常简单的解决方案是在DockPanel内部硬编码宽度,而不是使用附加属性:
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<DockPanel>
<Label Content="{Binding Label}" Width="80" />
<TextBox Text="{Binding Value}"/>
</DockPanel>
</DataTemplate>
最后,如果您需要根据标签大小调整宽度,则可以使用具有共享大小的网格:
<DataTemplate DataType="{x:Type vm:SectionViewModel}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding ViewModels}"
Grid.IsSharedSizeScope="true" />
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Label}" />
<TextBox Text="{Binding Value}" Grid.Column="1" />
</DockPanel>
</DataTemplate>
WPF充满了可能性!
将您的DataTemplate(用于SectionViewModel)更改为使用ListBox代替那里的更通用的控件将是最简单的。 设置完成后,请更改要附加到ListBox的DataTemplate。
不幸的是,如果不进入更复杂的布局,就没有真正简单的方法来设置您要描述的控件。 我建议这样设置,然后如果您需要为列绑定到某个宽度,请将其附加到父控件(或设置一个确定最大宽度并将其全部绑定到该属性的属性)。
<ListBox ItemsSource="{Binding Path=ViewModels}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type vm:StringViewModel}">
<StackPanel Orientation="Horizontal">
<Label x:Name="Left" Content="{Binding Label}" Width="{Binding ElementName=SourceControlHere, Path=WidthToBindTo}"/>
<TextBox x:Name="Right" HorizontalAlignment="Stretch" Text="{Binding Value}" Width="{Binding ElementName=SourceControlHere, Path=WidthToBindTo2}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.