Настроить вложенный элемент управления в стиле BasedOn - PullRequest
0 голосов
/ 14 мая 2018

Я подхожу к WPF (в частности, я работаю над MVVM) и пытаюсь создать собственный стиль Window, который будет использоваться во всем приложении. То, что я хочу сделать, это создать базовый стиль, который будет определять цвет окна, границу, значок, заголовок и т. Д. Окно может быть изменяемого размера или подобного диалоговому окну, поэтому я использовал WindowChrome, чтобы установить «окно изменяемого размера», которое имеет минимизацию , максимизировать и закрыть кнопки по умолчанию, и это, на самом деле, с изменяемым размером. Для окна входа в систему я хотел бы иметь окно, которое использует базовый стиль, но пользователь не может изменить его размер или увеличить его, поэтому кнопка максимизации не должна быть видна вообще. Я работал над стилями BasedOn и могу успешно переопределять свойства, но мне не удается определить, какие кнопки могут или не могут быть видны внутри окна. Поэтому я пытаюсь изменить вложенный элемент управления пользовательского интерфейса (в данном случае StackPanel).

Вот базовый стиль, который я создал, который на данный момент содержит все свойства окна и кнопки окна (я постарался прокомментировать его как мог):

<ControlTemplate TargetType="{x:Type Window}" x:Key="DefaultWindowsTemplate">

    <!-- The outer border of the Window -->
    <Border Padding="{Binding OuterMarginSizeThickness, FallbackValue=10}">

        <!-- The inner border of the Window and the Window itself, from the contour line to the shadow -->
        <Grid>
            <Border CornerRadius="{Binding WindowCornerRadius}" 
                    BorderBrush="{StaticResource AlizarinBrush}" 
                    BorderThickness="{Binding OutlineBorderThickness, FallbackValue=1}"
                    Background="{StaticResource VoidnessBrush}">
                <Border.Effect>
                    <DropShadowEffect Color="{StaticResource Voidness}" ShadowDepth="0" Opacity="1"/>
                </Border.Effect>
            </Border>

            <!-- The Container grid, composed by the title bar and the content area -->
            <Grid>

                <!-- Rows definition -->
                <Grid.RowDefinitions>
                    <RowDefinition Height="{Binding TitleHeight, FallbackValue=30}"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>

                <!-- Title bar row that contains icon, title and window buttons -->
                <Grid Margin="{Binding TitleHeightMargin}" 
                      Background="{StaticResource VoidnessBrush}" 
                      Grid.Row="0" 
                      Panel.ZIndex="1"
                      >

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>

                    </Grid.ColumnDefinitions>

                    <!-- Window icon -->
                    <Button Margin="5 5 0 0" 
                            Style="{StaticResource WindowIconButtonStyle}" 
                            Command="{Binding MenuCommand}">

                        <Image Source="/Images/Logos/khm_logo_titlebar.png"/>

                    </Button>

                    <!-- Window title -->
                    <TextBlock Grid.Column="1"
                               Foreground="{StaticResource ConcreteBrush}"
                               Margin="15 5 0 0"
                               TextAlignment="Center"
                               VerticalAlignment="Center"
                               HorizontalAlignment="Left"
                               Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title, FallbackValue='Window Title'}"/>

                    <!-- Window buttons - THIS IS THE CONTROL I WANT TO DEFINE INSIDE 'BASED ON' STYLES, WHERE I WILL NOT HAVE THE MAXIMIZE BUTTON -->
                    <StackPanel Grid.Column="2"
                                Orientation="Horizontal">

                        <Button Style="{StaticResource WindowButtonsStyle}"
                                Content="0"
                                Command="{Binding MinimizeCommand}"/>

                        <ToggleButton Style="{StaticResource MaximizeWindowButtonStyle}"
                                      Command="{Binding MaximizeCommand}"/>

                        <Button Style="{StaticResource WindowCloseButtonStyle}"
                                Content="r"
                                Command="{Binding CloseCommand}"/>

                    </StackPanel>

                </Grid>

                <!-- The Window content -->
                <Grid Margin="1 5 0 0" Grid.Row="1">
                    <ContentPresenter/>
                </Grid>

            </Grid>
        </Grid>
    </Border>

</ControlTemplate>

<Style TargetType="Window" x:Key="DefaultWindowsStyle">
    <Setter Property="Template" Value="{StaticResource DefaultWindowsTemplate}"/>
    <Setter Property="MinWidth" Value="{Binding WindowMinWidth}"/>
    <Setter Property="MinHeight" Value="{Binding WindowMinHeight}"/>
    <Setter Property="WindowStyle" Value="None"/>
    <Setter Property="AllowsTransparency" Value="True"/>
</Style>

Затем я начинаю редактировать базовый стиль следующим образом (конечно, в другом файле XAML):

<Style TargetType="Window" x:Key="DialogWindowsStyle" BasedOn="{StaticResource DefaultWindowsStyle}">
    <!-- REMOVE THE MAXIMIZE BUTTON INSIDE THE NESTED STACK PANEL -->
</Style>

Так, как правильно редактировать часть пользовательского интерфейса, используя тот же стиль?

Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 14 мая 2018

Я бы определил логические присоединенные свойства local:WindowExt.ShowMaximizeButton и т. Д. Со значениями по умолчанию true.В ControlTemplate я бы применил их к кнопкам с TemplateBindings и установил их с помощью установщиков стилей (или непосредственно на элементах Window в XAML).

Вот пример ShowMaximizeButton;остальные - это одно и то же с разными именами.Когда вы копируете и вставляете определение свойства зависимости, будьте осторожны, обновляя имя свойства в каждом месте, где оно появляется.Я использую фрагменты для их создания, чтобы минимизировать неосторожные ошибки.

public static class WindowExt
{
    public static bool GetShowMaximizeButton(Window obj)
    {
        return (bool)obj.GetValue(ShowMaximizeButtonProperty);
    }

    public static void SetShowMaximizeButton(Window obj, bool value)
    {
        obj.SetValue(ShowMaximizeButtonProperty, value);
    }

    public static readonly DependencyProperty ShowMaximizeButtonProperty =
        DependencyProperty.RegisterAttached("ShowMaximizeButton", typeof(bool), typeof(WindowExt),
            new PropertyMetadata(true));
}

Убедитесь, что это где-то до того, где определен шаблон элемента управления окном, в том же словаре ресурсов:

    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />

Кнопка максимизации в шаблоне элемента управления окном.Не будет никаких изменений в шаблоне элемента управления, кроме добавления этих соответствующих атрибутов видимости к кнопкам.Обратите внимание на скобки на Пути Связывания;это очень важно, потому что это идентификатор из нескольких частей для одного свойства.

<ToggleButton 
    Style="{StaticResource MaximizeWindowButtonStyle}"
    Command="{Binding MaximizeCommand}"
    Visibility="{TemplateBinding local:WindowExt.ShowMaximizeButton, Converter={StaticResource BooleanToVisibilityConverter}}"
    />

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

<Style TargetType="Window">
    <Setter Property="local:WindowExt.ShowMaximizeButton" Value="True" />
</Style>

Обратите внимание, что присоединенные свойства являются свойствами зависимостей самого элемента управления и не имеют никакого отношения к каким-либо объектам DataContexts или моделям представления.

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