Помещение ContentControl * внутри * шаблона данных WPF? - PullRequest
2 голосов
/ 20 января 2010

У меня есть пользовательский элемент управления Expander, который называется SpecialExpander. Это просто стандартный Expander с причудливым заголовком и парой свойств (HeaderText и IsMarkedRead).

Я начал с создания простого класса:

public class SpecialExpander : Expander
{
    public string HeaderText { get; set; }
    public bool IsMarkedRead { get; set; }
}

Затем я создал стиль, который устанавливает пару свойств в расширителе (например, поля, отступы и т. Д.) И, что важно, он также определяет пользовательский DataTemplate для свойства HeaderTemplate. Шаблон в основном представляет собой сетку из двух строк.

Как показано на рисунках ниже ...

  • для верхнего ряда, я бы хотел фиксированный макет (это всегда TextBlock TextBlock CheckBox)
  • для нижнего ряда, однако я хочу иметь возможность предоставлять собственный XAML для каждого расширителя.

Я пытался вставить <ContentControl Grid.Row="1" ... /> в DataTemplate, но я не мог понять, как его правильно подключить.


альтернативный текст http://img85.imageshack.us/img85/1194/contentcontrolwithintem.jpg


alt text


Вопрос

Как создать DataTemplate для моего SpecialExpander, чтобы заголовок содержал фиксированный контент (верхняя строка) и заполнитель для пользовательского контента (нижняя строка)?

Для второй иллюстрации я бы хотел сделать что-то вроде этого:

<SpecialExpander HeaderText="<Expander Header Text>" IsMarkedRead="True">
    <SpecialExpander.Header>
        <StackPanel Orientation="Horizontal">
            <RadioButton Content="High" />
            <RadioButton Content="Med" />
            <RadioButton Content="Low" />
        </StackPanel>
    <SpecialExpander.Header>
    <Grid>
        <Label>Main Content Goes Here</Label>
    </Grid>
</SpecialExpander>

1 Ответ

1 голос
/ 21 января 2010

Сегодня утром меня поразило, как решить эту проблему: вместо создания SpecialExpander мне просто нужен нормальный Expander.Затем для заголовка я буду использовать пользовательский ContentControl с именем SpecialExpanderHeader.

Вот как это работает ...

Класс SpecialExpanderHeader:

public class SpecialExpanderHeader : ContentControl
{
    public string HeaderText { get; set; }
    public bool IsMarkedRead { get; set; }
}

Стиль SpecialExpanderHeader:

<Style TargetType="custom:SpecialExpanderHeader">
    <Setter Property="Padding" Value="10" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="custom:SpecialExpanderHeader">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="5" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <StackPanel Grid.Row="0" Orientation="Horizontal">
                        <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=custom:SpecialExpanderHeader}, Path=HeaderText}" />
                        <CheckBox Margin="100,0,0,0" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=custom:SpecialExpanderHeader}, Path=IsMarkedRead}" />
                    </StackPanel>
                    <Separator Grid.Row="1" />
                    <ContentPresenter Grid.Row="2" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Стиль расширителя

<Style x:Key="Local_ExpanderStyle" TargetType="Expander" BasedOn="{StaticResource {x:Type Expander}}">
    <Setter Property="Margin" Value="0,0,0,10" />
    <Setter Property="Padding" Value="10" />
    <Setter Property="FontSize" Value="12" />
</Style>

Использование

<Expander Style="{StaticResource Local_ExpanderStyle}">
    <Expander.Header>
        <custom:SpecialExpanderHeader IsMarkedRead="True" HeaderText="Test">
            <StackPanel Orientation="Horizontal">
                <RadioButton Content="High" />
                <RadioButton Content="Medium" />
                <RadioButton Content="Low" />
            </StackPanel>
        </custom:SpecialExpanderHeader>
    </Expander.Header>
    <Grid>
        <!-- main expander content goes here -->
    </Grid>
</Expander>
...