自定义DataTemplate - Control不占用整个网格列宽

Nay*_*yan 1 c# wpf datatemplate

我对列表框中自定义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>
Run Code Online (Sandbox Code Playgroud)

如您所见,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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


现在,当我在列表框中加载数据时,

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;
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我看到frameworkelement Editor没有使用Grid的第三列所指示的完整行宽.

这就是行的样子(Snoop的截图).请注意,带有文本"Tester"的文本框未使用第3列的完整宽度.Snoop告诉我,ContentPresenterListBoxItem默认模板中没有使用全宽,即使Bd边框确实如此(注意Bd的 ActualWidth )! 这是行的样子(Snoop的截图)

如何更改DataTemplate以便Editor使用完整的列宽?

非常感谢!

Roh*_*ats 5

设置HorizontalContentAlignmentStretchListBoxItem.它可以在ItemContainerStyle.

<ListBox x:Name="lv" ItemTemplate="{StaticResource PropertyListTemplate}"
         Background="Green">
   <ListBox.ItemContainerStyle>
      <Style TargetType="ListBoxItem">
          <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
      </Style>
   </ListBox.ItemContainerStyle>
</ListBox>
Run Code Online (Sandbox Code Playgroud)