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

时间:2013-12-14 16:57:05

标签: 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>

如您所见,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 )! This is how the row looks like (screenshot of Snoop)

如何更改DataTemplate以使Editor使用整列宽度?

非常感谢!

1 个答案:

答案 0 :(得分:5)

HorizontalContentAlignment设置StretchListBoxItem。可以在ItemContainerStyle中完成。

<ListBox x:Name="lv" ItemTemplate="{StaticResource PropertyListTemplate}"
         Background="Green">
   <ListBox.ItemContainerStyle>
      <Style TargetType="ListBoxItem">
          <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
      </Style>
   </ListBox.ItemContainerStyle>
</ListBox>