Изменение цвета фона кнопки при наведении на нее [дублировать]

Я не сохраняю interface s - самое важное в языке: он чаще всего используется для наследования класса. Но в любом случае они важны! Например (это Java код, но он может просто адаптироваться к C# или многим другим языкам):

interface Convertable<T> {

    T convert();
}

public class NumerableText implements Convertable<Integer> {

    private String text = "";

    public NumerableText() { }

    public NumerableText(String text) {
        this.text = text;
    }

    public String getText() {
        return this.text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Integer convert() {
        return this.text.hashCode();
    }
}

public class NumerableTextArray implements Convertable<Integer> {

    private String[] textArray = "";

    public NumerableTextArray() { }

    public NumerableTextArray(String[] textArray) {
        this.textArray = textArray;
    }

    public String[] getTextArray() {
        return this.textArray;
    }

    public void setTextArray(String[] text) {
        this.textArray = textArray;
    }

    public Integer convert() {
        Integer value = 0;
        for (String text : textArray)
            value += text.hashCode();
        return value;
    }
}

public class Foo {

    public static void main() {
        Convertable<Integer> num1 = new NumerableText("hello");
        Convertable<Integer> num2 = new NumerableTextArray(new String[] { "test n°1", "test n°2" });
        System.out.println(String.valueOf(num1.convert()));
        System.out.println(String.valueOf(num2.convert()));
        //Here are you two numbers generated from two classes of different type, but both with the method convert(), which allows you to get that number.
    }
}
66
задан ASh 26 August 2015 в 09:30
поделиться

5 ответов

Чтобы удалить поведение по умолчанию MouseOver по умолчанию на Button, вам необходимо изменить ControlTemplate. Изменение вашего определения Style следующим образом должно сделать трюк:

<Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="Red"/>
        </Trigger>
    </Style.Triggers>
</Style>

EDIT: это на несколько лет позже, но вы действительно можете установить кисть границы внутри границы, которая находится там , Idk, если бы это было указано, но похоже, что это не было ...

122
ответ дан Drew Noakes 22 August 2018 в 18:54
поделиться
  • 1
    Да, это работает. Но все же, никаких объяснений ПОЧЕМУ ... – C-F 1 August 2014 в 03:25
  • 2
    Это работает, однако кнопка Borders исчезнет! Если бы поставить & lt; BorderBorderBrush = & quot; DarkGray & quot; BorderThickness = & Quot; 1 & Quot; & GT; элемент вокруг кнопки. – Venugopal M 6 March 2015 в 09:16
  • 3
    @ C-F, причина этого в стандарте . Стиль кнопки имеет триггеры внутри ControlTemplate, поэтому они переопределяют триггеры Style OP. – torvin 22 September 2015 в 02:01
  • 4
    @torvin Это кажется таким обратным! Почему пользовательский триггер должен быть переопределен по умолчанию? Я понимаю иерархию, ControlTemplate выше стиля, но я не понимаю, почему это так сложно переопределить базовые настройки, подобные этим. – Fuselight 4 November 2015 в 05:11
  • 5
    @Fuselight, триггер внутри ControlTemplate в основном говорит: «Покрасьте границу в соответствии с цветом Background. И если мышь над кнопкой - нарисуйте эту границу вместо этого цвета », в то время как в стиле вы имеете доступ только к цвету Background, а не к базовому цвету границы. Я вижу, что вы указываете, что стиль WPF оставляет желать лучшего ... – torvin 4 November 2015 в 05:25

Это хорошо сработало для меня.

Стиль кнопки

<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border>
                    <Border.Style>
                        <Style TargetType="{x:Type Border}">
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="DarkGoldenrod"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Border.Style>
                    <Grid Background="Transparent">
                        <ContentPresenter></ContentPresenter>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Кнопка

<Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25"
        Command="{Binding CloseWindow}">
    <Button.Content >
        <Grid Margin="0 0 0 0">
            <Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" />
        </Grid>
    </Button.Content>
</Button>

Примечания

  • Кнопка отображает маленький синий крест, как и тот, который использовался для закрытия окна.
  • Установив фон сетки на «Прозрачный», он добавляет hittest, что означает, что если мышь в любом месте над кнопкой, тогда это сработает. Опустите этот тег, и кнопка загорится, если мышь находится над одной из векторных линий в значке (это не очень удобно).
6
ответ дан Contango 22 August 2018 в 18:54
поделиться
  • 1
    Это отличный ответ, но как насчет изменения цвета Stroke при наведении на Border, но без зависания над Path? – Nate 5 August 2016 в 15:33

Несколько более сложный ответ, который использует ControlTemplate и имеет эффект анимации (адаптирован из https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance- )

В вашем ресурсном словаре определите шаблон управления для вашей кнопки, такой как этот:

<ControlTemplate TargetType="Button" x:Key="testButtonTemplate2">
    <Border Name="RootElement">
        <Border.Background>
            <SolidColorBrush x:Name="BorderBrush" Color="Black"/>
        </Border.Background>

        <Grid Margin="4" >
            <Grid.Background>
                <SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/>
            </Grid.Background>
            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/>
        </Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Border>
</ControlTemplate>

в вашем XAML, который вы можете использовать шаблон выше для вашей кнопки, как показано ниже:

Определите свою кнопку

<Button Template="{StaticResource testButtonTemplate2}" 
HorizontalAlignment="Center" VerticalAlignment="Center" 
Foreground="White">My button</Button>

Надеюсь, что это поможет

2
ответ дан Iakobos Karakizas 22 August 2018 в 18:54
поделиться

Просто хочу разделить мой стиль кнопки из моего ResourceDictionary, который я использовал. Вы можете свободно изменять фон onHover в триггерах стиля. " ColorAnimation To = * ваш желаемый BG (i.e # FFCEF7A0)". Кнопка BG также автоматически вернется к исходному BG после состояния mouseOver. Вы даже можете установить, насколько быстро переход.

Словарь ресурсов

<Style x:Key="Flat_Button" TargetType="{x:Type Button}">
    <Setter Property="Width" Value="100"/>
    <Setter Property="Height" Value="50"/>
    <Setter Property="Margin" Value="2"/>
    <Setter Property="FontFamily" Value="Arial Narrow"/>
    <Setter Property="FontSize" Value="12px"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Foreground">
        <Setter.Value>
            <SolidColorBrush Opacity="1" Color="White"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Background" >
        <Setter.Value>
            <SolidColorBrush Opacity="1" Color="#28C2FF" />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">

                <Border x:Name="border"
                         SnapsToDevicePixels="True"
                         BorderThickness="1"
                         Padding="4,2"
                         BorderBrush="Gray"
                         CornerRadius="3"
                         Background="{TemplateBinding Background}">
                    <Grid>
                        <ContentPresenter 
                        Margin="2"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        RecognizesAccessKey="True" />

                    </Grid>
                </Border>

            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation To="#D2F898"
                                        Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" 
                                        FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation
                                            Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" 
                                            FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>

        </Trigger>


    </Style.Triggers>
</Style>

все, что вам нужно сделать, это вызовите стиль.

Пример реализации

<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">  
     <StackPanel>
     <TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
     </StackPanel>
</Button>
3
ответ дан Justin Adrias 22 August 2018 в 18:54
поделиться

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

В случай обращения с эффектом наведения на кнопку WPF, изменение внешнего вида в элементе WPF Button вызвано Trigger в стиле по умолчанию для Button, который основан на свойстве IsMouseOver и устанавливает свойства Background и BorderBrush элемента верхнего уровня Border в шаблоне управления. Фон элемента Button находится под фоном элемента Border, поэтому изменение свойства Button.Background не мешает видеть эффект зависания.

С некоторыми усилиями вы можете отменить это поведение с помощью ваш собственный сеттер, но поскольку элемент, который вам нужно затронуть, находится в шаблоне, а не напрямую доступен в вашем собственном XAML, этот подход будет сложным, а IMHO слишком сложным.

Еще один вариант - использовать как Content для Button, а не Background. Если вам нужен дополнительный контент по графике, вы можете объединить их с Grid в качестве объекта верхнего уровня в контенте.

Однако, если вы буквально просто хотите полностью отключить эффект наведения (скорее чем просто сокрытие), вы можете использовать Visual Studio XAML Designer:

  1. Во время редактирования вашего XAML выберите вкладку «Дизайн» .
  2. На вкладке «Дизайн» найдите кнопку, для которой вы хотите отключить эффект.
  3. Щелкните правой кнопкой мыши эту кнопку и выберите «Редактировать шаблон / Изменить Копия ... ". Выберите в подсказке, где вы хотите разместить новый ресурс шаблона. Это будет ничего не делать, но на самом деле Дизайнер добавит новые ресурсы, где вы сказали, и изменил элемент кнопки, чтобы ссылаться на стиль, который использует эти ресурсы в качестве шаблона кнопки.
  4. Теперь вы может пойти редактировать этот стиль. Самое простое - удалить или закомментировать (например, Ctrl + E, C) элемент <Trigger Property="IsMouseOver" Value="true">...</Trigger>. Конечно, вы можете внести любые изменения в желаемый шаблон.

Когда вы закончите, стиль кнопки будет выглядеть примерно так:

<p:Style x:Key="FocusVisual">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</p:Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<p:Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
  <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
  <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
  <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
  <Setter Property="BorderThickness" Value="1"/>
  <Setter Property="HorizontalContentAlignment" Value="Center"/>
  <Setter Property="VerticalContentAlignment" Value="Center"/>
  <Setter Property="Padding" Value="1"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
          <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsDefaulted" Value="true">
            <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
          </Trigger>
          <!--<Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
          </Trigger>-->
          <Trigger Property="IsPressed" Value="true">
            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
            <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</p:Style>

(Примечание: вы можете опустить квалификацию пространства имен p: XML в фактическом коде & hellip; я предоставляю их здесь только потому, что форматировщик XML-кода Stack Overflow путается элементами <Style/>, которые не имеют полностью квалифицированного имени с пространством имен XML.)

Если вы хотите применить тот же стиль к другим кнопкам, вы можете просто щелкнуть их правой кнопкой мыши и выбрать «Редактировать шаблон / применить ресурс» и выбрать стиль, который вы только что добавили для первой кнопки. Вы даже можете сделать стиль стилем по умолчанию для всех кнопок, используя обычные методы применения стиля по умолчанию к элементам в XAML.

0
ответ дан Peter Duniho 22 August 2018 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: