wpf newbie - 如何布局变量属性集,使它们与固定属性出现在同一列中

时间:2010-01-06 10:33:27

标签: wpf layout grid

我是一名wpf新手&爱它。但是我有一个布局问题,我希望有人可以帮助我。我需要构建一个人物属性编辑器。它们由2个固定属性组成 - 名字和名字。姓氏,加上其他属性的变量桶,如年龄,性别等。

我构建了一个由网格组成的对话框,其中包含2个固定属性的文本框和一个变量属性的列表框。

<Grid Name="mainGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="10"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Label Grid.Column="0" Grid.Row="0" VerticalAlignment="Center">First Name:</Label>  
    <TextBox Name="tbFirstName" Grid.Column="2" Grid.Row="0" MinWidth="100" Margin="5" Text="{Binding Path=FirstName}"/>

    <Label Grid.Column="0" Grid.Row="1" VerticalAlignment="Center">Last Name:</Label>
    <TextBox Name="tbLastName" Grid.Column="2" Grid.Row="1" MinWidth="100" Margin="5" Text="{Binding Path=LastName, UpdateSourceTrigger=PropertyChanged}"/>     

    <ListBox Name="lstAttributes" Grid.Row="2" Grid.ColumnSpan="3" ItemsSource="{Binding Path=Attributes, UpdateSourceTrigger=PropertyChanged}"/>

    <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Right">
        <Button Name="btnOk" IsDefault="True" Click="btnOk_Click" Grid.Column="0" Grid.Row="2" MinWidth="60" Margin="5">Ok</Button>
        <Button Name="btnCancel" IsCancel="True" Grid.Column="0" Grid.Row="2" MinWidth="60" Margin="5">Cancel</Button>
    </StackPanel>

</Grid>

我有一个数据层,它返回绑定的person对象。这包含属性列表 绑定到列表框。为了支持不同类型的属性,这些属性来自公共基类。即IntegerAttribute:AttributeBase用于表示'Age'属性。

然后,我根据属性的类型使用数据模板呈现正确的控件:

<Window.Resources>
        <DataTemplate DataType="{x:Type reg:IntegerAttribute}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Grid.Column="1" Text="{Binding Name}"/>
                <TextBox Grid.Column="3" Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
        </DataTemplate>
        <DataTemplate DataType="{x:Type reg:TextAttribute}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}"/>
                <TextBox Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>           
        </DataTemplate>
        <DataTemplate DataType="{x:Type reg:SingleChoiceAttribute}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}"/>
                <ComboBox ItemsSource="{Binding Path=Choices, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

但这是问题所在。我希望变量集属性与固定属性出现在同一列中。我尝试使用SharedSizeGroup,但这似乎不起作用。

非常感谢,

NickD

1 个答案:

答案 0 :(得分:0)

在自定义属性数据模板中,不要使用堆栈面板,尝试使用包含3列的网格(如包含网格,在内部网格上将IsSharedSizeScope设置为false,在外部网格上设置为true),并使用SharedGroupSize两个网格。

示例:

<Window.Resources>
    <DataTemplate DataType="{x:Type reg:IntegerAttribute}">
        <Grid IsSharedSizeScope="False">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="groupa" Width="*"/>
                <ColumnDefinition SharedSizeGroup="groupb" Width="10"/>
                <ColumnDefinition SharedSizeGroup="groupc" Width="*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="1" Text="{Binding Name}"/>
            <TextBox Grid.Column="3" Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}"/>
        </Grid>
    </DataTemplate>
...
<Grid Name="mainGrid" IsSharedSizeScope="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition SharedSizeGroup="groupa" Width="*"/>
        <ColumnDefinition SharedSizeGroup="groupb" Width="10"/>
        <ColumnDefinition SharedSizeGroup="groupc" Width="*"/>
    </Grid.ColumnDefinitions>
...

请注意,如果我没记错的话,共享大小组只能使用自动宽度列,因此上面示例的某些列定义可能需要更改为自动宽度。

另一方面,由于您的列都不是自动宽度,因此您可能根本不使用共享组大小,因为列宽仍然会匹配。

这是一个完整的例子(不需要任何代码)来证明这一点:

<Window x:Class="gridsh.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <x:ArrayExtension x:Key="data" Type="{x:Type sys:String}">
            <sys:String>Test1</sys:String>
            <sys:String>Test2</sys:String>
            <sys:String>Test3</sys:String>
            <sys:String>Test4</sys:String>
        </x:ArrayExtension>
        <DataTemplate DataType="{x:Type sys:String}">
            <Grid Grid.IsSharedSizeScope="False">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="groupa" Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Border BorderBrush="Black" BorderThickness="1">
                    <TextBlock Text="xxxxxx"/>
                </Border>
                <TextBlock Text="{Binding}" Grid.Column="1"/>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <Grid Grid.IsSharedSizeScope="True">
        <Grid Grid.IsSharedSizeScope="False" Height="30" VerticalAlignment="Top" Margin="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="groupa" Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Border BorderBrush="Black" BorderThickness="1">
                <TextBlock Text="WWWWWWWWWWWWWWWWWWWWWWW"/>
            </Border>
            <TextBlock Text="dgdfsg" Grid.Column="1"/>
        </Grid>
        <ListBox ItemsSource="{StaticResource data}" Margin="0,36,0,0" BorderThickness="0" Padding="0"/>
    </Grid>
</Window>