WPF Визуальное наследование - PullRequest
2 голосов
/ 24 июня 2011

Нужен совет (лучше из ваших реальных проектов) - каков наилучший способ сделать визуальное наследование в WPF?

Более конкретно: Как интегрировать вид окна с помощью строки состояния?

Невозможно перехватить один файл xaml из другого.Затем, вы создаете пользовательский элемент управления MyStatusbar и вставляете его на каждую страницу?

Можно создать шаблон стиля для базового окна и использовать стиль inhertence, однако это только для простых визуальных свойств (цвет, размер).Вторая идея - создать базовый DataTemplate, но нет наследования.

PS В WinForms есть базовая форма со строкой состояния и некоторой логикой.После добавления свойства

public string StatusbarText {set{baseStatusbar.Text = value;}}

очень просто использовать свойство в дочерних формах.Кроме того, у нас есть наследование представлений в строке состояния.

Я знаю, как встроить логику в WPF, но что делать с визуализацией.

Ответы [ 2 ]

1 голос
/ 24 июня 2011

Вы, конечно, можете создать собственный элемент управления Window, который добавляет свойство StatusbarText. В качестве альтернативы, вы можете использовать собственный стиль для окна, единственный вопрос - как передать элементы строки состояния в ваш стиль. Для этого вы можете использовать прикрепленные свойства .

Если вы идете по этому маршруту, вы не сможете унаследовать свой собственный стиль от стиля по умолчанию, так как вам нужно полностью переопределить ControlTemplate. Стиль для окна будет выглядеть так:

<ControlTemplate x:Key="WindowTemplateKey"
                 TargetType="{x:Type Window}">
    <Border Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}">
        <Grid>
            <AdornerDecorator>
                <DockPanel>
                    <StatusBar DockPanel.Dock="Bottom" ItemsSource="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
                    <ContentPresenter/>
                </DockPanel>
            </AdornerDecorator>

            <ResizeGrip x:Name="WindowResizeGrip"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Bottom"
                        Visibility="Collapsed"
                        IsTabStop="false"/>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="Window.ResizeMode"
                           Value="CanResizeWithGrip"/>
                <Condition Property="Window.WindowState"
                           Value="Normal"/>
            </MultiTrigger.Conditions>
            <Setter TargetName="WindowResizeGrip"
                    Property="Visibility"
                    Value="Visible"/>
        </MultiTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>


<Style x:Key="{x:Type Window}"
       TargetType="{x:Type Window}">
    <Setter Property="Foreground"
            Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
    <Setter Property="Background"
            Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <AdornerDecorator>
                        <DockPanel>
                            <StatusBar DockPanel.Dock="Bottom" ItemsSource="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
                            <ContentPresenter/>
                        </DockPanel>
                    </AdornerDecorator>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Window.ResizeMode"
                 Value="CanResizeWithGrip">
            <Setter Property="Template"
                    Value="{StaticResource WindowTemplateKey}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Если вы используете стиль выше, вы можете установить свойство Window.Tag, чтобы оно представляло собой список элементов, которые вы хотите отображать в StatusBar. Самая большая проблема в этом подходе - вам нужно добавить прикрепленные свойства для таких вещей, как StatusBar.ItemContainerStyle , чтобы вы могли настроить внешний вид строки состояния.

То же самое верно, если вы используете DataTemplate. Так что, если вы знаете, что вам нужен только один текст в StatusBar, вы можете использовать приведенное выше в ControlTemplates выше и установить Window.Tag в строку (или использовать присоединенное свойство).

<StatusBar DockPanel.Dock="Bottom">
    <StatusBarItem Content="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
</StatusBar>
1 голос
/ 24 июня 2011

Лучше использовать MVVM, посмотрите Приложения WPF с шаблоном проектирования Model-View-ViewModel

Вы можете написать базовую ViewModel со свойством StatusbarText и затем наследовать от базовойViewModel.

Затем вы можете использовать это свойство ViewModel с привязкой данных в стилях и шаблонах, посмотрите Настройка отображения данных с привязкой данных и WPF

Также посмотрите на этот вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...