Если вы хотите контролировать ширину в содержащем шаблоне, вы можете использовать унаследованное вложенное свойство:
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 просто полон возможностей!