wpf newbie - как разместить переменный набор атрибутов, чтобы они отображались в тех же столбцах, что и фиксированные атрибуты - PullRequest
0 голосов
/ 06 января 2010

Я новичок в 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 голосов
/ 06 января 2010

В своих шаблонах данных пользовательских свойств вместо использования панели стека попробуйте использовать сетку из 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>
...