我对列表框中自定义datatemplate的布局感到困惑。 问题是每个ListBoxItem都不占用整行宽。
这是ListBox的DataTemplate:
<Window x:Class="NewPropertyGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NewPropertyGrid"
Title="MainWindow" Height="200" Width="300">
<Window.Resources>
<DataTemplate x:Key="PropertyListTemplate">
<Grid Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=PropType,Converter={local:PropTypeToString}}"
Margin="1"
VerticalAlignment="Center"
Background="LightGray"
Foreground="Black"
/>
<TextBlock Grid.Column="1"
Text="="
Margin="1"
Background="LightGray"
Foreground="Black"
/>
<ContentControl Grid.Column = "2"
Content = "{Binding Editor}"
HorizontalAlignment = "Stretch"
VerticalAlignment = "{Binding VerticalContentAlignment}"
/>
</Grid>
</DataTemplate>
</Window.Resources>
<ListBox x:Name="lv" ItemTemplate="{StaticResource PropertyListTemplate}" Background="Green" />
</Window>
如您所见,Grid中有3列。第三个应该是Editor
(FrameworkElement),通过后面的代码决定。以下是作为信息来源的类数据结构:
namespace NewPropertyGrid {
public enum PropType { Name, Age, Surname };
public class PropItem {
public PropType PropType { get; set; }
object _Value = null;
internal object Value {
get {
return _Value;
}
set {
_Value = value;
DetectEditor();
}
}
public FrameworkElement Editor { get; set; }
public void DetectEditor() {
var t = Value.GetType();
if (t == typeof(string)) {
var txt = new TextBox();
txt.Text = Value as string;
Editor = txt;
}
else if (t.IsArray) {
var cmb = new ComboBox();
cmb.ItemsSource = (IEnumerable)Value;
if (cmb.Items.Count > 0)
cmb.SelectedIndex = 0;
Editor = cmb;
}
}
}
}
现在,当我在列表框中加载数据时,
namespace NewPropertyGrid {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
Loaded += (s, e) => {
var list = new List<PropItem>();
list.Add(new PropItem() {
PropType = global::NewPropertyGrid.PropType.Name,
Value = "Tester"
});
list.Add(new PropItem() {
PropType = global::NewPropertyGrid.PropType.Surname,
Value = new string[] { "X", "Y", "Z" }
});
lv.ItemsSource = list;
};
}
}
}
我看到frameworkelement Editor
没有使用网格第三列所指示的完整行宽。
这就是行的样子(Snoop的截图)。请注意,带有文本“Tester”的文本框未使用第3列的完整宽度。 Snoop告诉我,ListBoxItem默认模板中的ContentPresenter
未使用全宽,即使 Bd 边框确实如此(请注意 Bd 的ActualWidth )!
如何更改DataTemplate以使Editor
使用整列宽度?
非常感谢!
答案 0 :(得分:5)
为HorizontalContentAlignment
设置Stretch
至ListBoxItem
。可以在ItemContainerStyle
中完成。
<ListBox x:Name="lv" ItemTemplate="{StaticResource PropertyListTemplate}"
Background="Green">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>