Как установить конкретные параметры элемента управления, которые переопределяют глобальный стиль в WPF? - PullRequest
0 голосов
/ 02 февраля 2019

Я определил глобальный стиль для кнопок в своем приложении через словарь ресурсов для всего приложения.Стиль выглядит следующим образом (из другого примера SO):

<Style TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="{DynamicResource BaseButtonBG}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <Grid Background="{TemplateBinding Background}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>
<Style.Triggers>
    <!-- Triggers here -->>
</Style.Triggers>

Работает.Но мне нужно назначить конкретные значения непосредственно для некоторых из моих кнопок, таких как поля и отступы, чтобы выровнять их.Я также хотел бы иметь возможность переопределять свойства цвета из стиля в отдельных кнопках.

Похоже, что любые свойства, которые я устанавливаю непосредственно для определенных кнопок, полностью игнорируются, и используются только свойства из глобального стиля.,Как мне преодолеть это?

ОБНОВЛЕНИЕ: Чтобы уточнить, что я хочу: В мире HTML / CSS (который старше, чем грязь), вы можете добавить класс стиля к элементу,но вы также можете назначить свойства непосредственно элементу, который переопределяет значения класса.Это то, чего я хочу достичь в WPF.

ОБНОВЛЕНИЕ 2 Возможно, люди считают этот вопрос глупым, потому что решение должно быть очевидным.Однако, из моего личного тестирования, кажется, что ошибка с Padding вообще не меняется, если вы специально не связали ее в шаблоне управления.Такое поведение, кажется, меняется от собственности к собственности.Так как моя первоначальная попытка переопределить свойство было связано с Padding, и оно не сработало, мне пришлось создать этот обходной путь.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

ДА: это полностью выполнимо, Вы можете назначить переопределяющие свойства непосредственно на элемент, не выполняя уродливый процесс, который многие используют для создания специальной одноразовой словарной записи только для конкретного рассматриваемого элемента.

Я не знаю, вызвано ли это ошибкой в ​​WPF, но есть начальное требование ...

Ваш базовый стиль, на который ссылается словарь, может включать в себя любые свойства, которые вы хотите использоватьпереопределение.По какой-то причине разные свойства проявляют разное поведение.Но, по крайней мере, в случае Padding, если вы не включите Padding в свой шаблон TemplateBinding ControlTemplate, вы не сможете переопределить его в своем элементе.

Кроме того, в случае поля, кажется,быть своего рода эффектом «удвоения», который происходит, если вы включаете Margin в ControlTemplate TemplateBinding.Если вы не используете шаблон для слепого поля, вы все равно можете переопределить поле, но его поведение изменится.

ШАГ 1

Определение базового стиля с помощью ControlTemplate.Убедитесь, что ваш ControlTemplate включает в себя TemplateBinding для всех свойств, которые вы можете настроить / переопределить для отдельных элементов.

<Style TargetType="Button">
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="Background" Value="{StaticResource BaseButtonBG}"/>
    <Setter Property="Margin" Value="0"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border 
                    Background="{TemplateBinding Background}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}"
                    Margin="{TemplateBinding Margin}"
                    >
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="{StaticResource BaseButtonBG_IsMouseOver}"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background" Value="{StaticResource BaseButtonBG_IsPressed}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Я определил несколько ключей StaticResource для цветов своих свойств, чтобы я мог их поместитьвообще в другом месте для более чистой кожи.Вот эти ключи:

<SolidColorBrush x:Key="BaseButtonBG"                   Color="#5f636c"/>
<SolidColorBrush x:Key="BaseButtonBG_IsMouseOver"       Color="#898C94"/>
<SolidColorBrush x:Key="BaseButtonBG_IsPressed"         Color="#484B51"/>

ШАГ 2

Реализуйте действительную кнопку следующим образом:

<Button Content="New" />

И результат этого делаеткнопка, которая выглядит следующим образом:

Initial Button Style

ШАГ 3

Теперь, скажем, я хочу, чтобы все мои кнопкичтобы выглядеть таким раздавленным, кроме одного.Я хочу добавить вертикальный отступ, чтобы одна конкретная кнопка выглядела выше.Я мог бы изменить пример кнопки следующим образом:

<Button Content="New" Padding="0,30"/>

И результат:

Altered Button Style

В качестве альтернативы, вы можете реализовать кнопкупереопределите следующим образом, что дает вам возможность переопределить триггеры или другие специальные опции стиля.

<Button Content="New">
    <Button.Style >
        <Style TargetType="Button" BasedOn="{DynamicResource {x:Type Button}}">
            <Setter Property="Padding" Value="0,30"/>
        </Style>
    </Button.Style>
</Button>

TADA!Мы установили одноразовую настройку стиля непосредственно на элемент ГДЕ ОНА!Нам не нужно было создавать стиль в словаре и ссылаться на него в этом одном случае.

Важные пункты

Для того, чтобы это сработало "Заполнение "ДОЛЖНО БЫТЬ определено в ControlTemplate с кодом TemplateBinding.Если вы этого не сделаете, Padding, непосредственно примененный к кнопке, просто полностью игнорируется.Опять же, я не уверен, почему это так, но это, кажется, волшебное исправление.

Дальнейшее чтение: Мне удалось выяснить это из некоторой полезной информации в этом блогеarticle:

явный-неявный-и-default-styles-in-wpf

Интересно, что в последней части этой статьи предлагается создать собственный элемент управления с вашим собственным значением по умолчаниюстиль и свойства, которые вы можете переопределить так же, как я сделал здесь.Это кажется мне немного излишним, но это может устранить странную проблему с ошибками, когда отступы и маржа ведут себя по-разному.Хотя еще не пробовал.

0 голосов
/ 02 февраля 2019

Хорошо, форма в дизайне:

enter image description here

XAML-код для формы:

<Window.Resources>

    <Style TargetType="Button">
        <Setter Property="Foreground" Value="Red"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid Background="{TemplateBinding Background}">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>


<Grid>
    <Button Content="Button" x:Name="btnNo1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120"/>
    <Button Content="Button" x:Name="btnNo2" HorizontalAlignment="Left" Margin="135,10,0,0" VerticalAlignment="Top" Width="120"/>

</Grid>

и в RunTime мы собираемся изменить Margin, используя этот код в файле CS:

public MainWindow()
{
    InitializeComponent();

    btnNo2.Margin = new Thickness(100, 100, 100, 100);
}

Результат будет:

enter image description here



Можете ли вы создать и использовать новый стиль для кнопки, где вам нужно пользовательское поле / отступы?

<Style x:Key="SpecialButtonType1" BasedOn="{StaticResource ResourceKey=CommonButtonStyle}">
...
</Style>

и изменение

<Style TargetType="Button">

до

<Style TargetType="Button" x:Key="CommonButtonStyle">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...