WPF에서 Button MouseOver의 배경을 어떻게 변경합니까?


93

이 XAML을 사용하는 내 페이지에 버튼이 있습니다.

<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" 
    Width="50" Height="50" HorizontalContentAlignment="Left" 
    BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Green"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

하지만 버튼 위에 마우스를 올리면 버튼의 배경이 기본 창 회색 배경으로 변경됩니다.
뭐가 문제 야?

이것은 mouseover 전후의 버튼 그림입니다.
이전 :
전에
이후 :
후


그러나 이미지를 시작 Forward-48.png하고 IsMouseOver를 트리거하여 동일한 Forward-48.png. 다른 이미지로 코드를 사용하려고하는데 모두 잘 작동했습니다.
Anatoliy Nikolaev

1
@anatoliy : 작동하지 않습니다.
세 페르 모하마디

다음은 기본 색상입니까? 버튼 배경을 변경하지 않거나 설정하지 않은 다른 곳은 없습니까? 귀하의 코드가 잘 작동합니다.
Anatoliy Nikolaev

답변:


174

기본 제거하려면 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>

편집 : 몇 년 늦었지만 실제로 거기에있는 테두리 안쪽에 테두리 브러시를 설정할 수 있습니다. 그것이 지적 되었다면 Idk하지만 그것이 아닌 것 같습니다 ...


1
이것은 작동하지만 버튼 테두리가 사라집니다! 버튼 주위에 <Border BorderBrush = "DarkGray"BorderThickness = "1"> 요소를 넣어야했습니다.
Venugopal M 2015 년

4
@CF 그 이유는 표준 Button 스타일 에 트리거가 ControlTemplate있으므로 OP의 Style트리거 를 재정의하기 때문 입니다.
Torvin 사용자

1
@torvin 너무 거꾸로 보인다! 사용자 정의 트리거가 기본 트리거로 대체되어야하는 이유는 무엇입니까? 계층 구조를 이해하고 ControlTemplate이 Style 위에 있지만 이와 같은 기본 설정을 재정의하는 것이 왜 그렇게 어려운지 이해하지 못합니다.
Fuselight 2015

@Fuselight, 내부 트리거는 ControlTemplate기본적으로 ' Background색 에 따라 테두리를 칠 합니다. 그리고 마우스가 버튼 위에 있으면-대신이 색 테두리를 칠하십시오. '스타일 Background에서는 기본 테두리 색이 아닌 색 에만 액세스 할 수 있습니다 . 하지만 WPF 스타일링은 원하는 것이 많이 남아 있습니다 ...
torvin

이렇게하면 배경이 투명한 이미지를 사용할 때 롤오버시 나타나는 파란색 상자를 제거하는 추가 이점이 있습니다. 내 경우에는 내가 0으로 경계, 그래서 세트의 경계선을 원하지 않았다
척 야만인

22

지금까지의 모든 대답은 기본 버튼 동작을 다른 것으로 완전히 바꾸는 것과 관련이 있습니다. 그러나 IMHO 는 XAML 요소의 기존 기본 템플릿을 편집하여 관심있는 부분 만 변경할 수 있다는 것을 이해하는 것이 유용하고 중요합니다 .

WPF 버튼의 호버 효과를 처리하는 경우 WPF Button요소의 모양 변경 은 속성을 기반으로하고 최상위 요소 의 및 속성을 설정하는 Trigger의 기본 스타일에서 발생 합니다. 컨트롤 템플릿에서. 요소의 배경은 아래입니다 변화하므로, 요소의 배경 재산 것은 본되는 호버 효과를 방지하지 않습니다.ButtonIsMouseOverBackgroundBorderBrushBorderButtonBorderButton.Background

약간의 노력으로이 동작을 고유 한 setter로 재정의 할 수 있지만 영향을 주어야하는 요소가 템플릿에 있고 자체 XAML에서 직접 액세스 할 수 없기 때문에 이러한 접근 방식은 어렵고 IMHO는 지나치게 복잡합니다.

또 다른 옵션은 같은 그래픽을 사용하도록하는 것입니다 Content에 대해 Button오히려보다 Background. 그래픽 위에 추가 콘텐츠가 필요한 경우 콘텐츠 Grid의 최상위 개체로 와 결합 할 수 있습니다 .

그러나 말 그대로 호버 효과를 숨기지 않고 완전히 비활성화하려는 경우 Visual Studio XAML 디자이너를 사용할 수 있습니다.

  1. XAML을 편집하는 동안 "디자인" 탭을 선택합니다 .
  2. 에서 "디자인" 탭, 당신이 효과를 해제하려는 버튼을 찾을 수 있습니다.
  3. 해당 버튼을 마우스 오른쪽 버튼으로 클릭하고 "템플릿 편집 / 사본 편집 ..."을 선택 합니다. 프롬프트에서 새 템플릿 리소스를 배치 할 위치를 선택합니다. 아무 작업도 수행하지 않는 것처럼 보이지만 실제로 Designer는 사용자가 말한 곳에 새 리소스를 추가하고 해당 리소스를 단추 템플릿으로 사용하는 스타일을 참조하도록 단추 요소를 변경합니다.
  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 네임 스페이스 제한을 생략 할 수 있습니다. 여기에서는 Stack Overflow XML 코드 포맷터가 <Style/>XML 네임 스페이스가있는 정규화 된 이름이없는 요소로 인해 혼동되기 때문에 여기에만 제공합니다 .)

다른 버튼에 동일한 스타일을 적용하려면 마우스 오른쪽 버튼을 클릭하고 "템플릿 편집 / 리소스 적용" 을 선택한 다음 첫 번째 버튼에 대해 방금 추가 한 스타일을 선택하면됩니다. XAML의 요소에 기본 스타일을 적용하는 일반적인 기술을 사용하여 해당 스타일을 모든 단추의 기본 스타일로 만들 수도 있습니다.


6
정말 고마워. 이것은 여기서 유일하게 용인 할 수있는 답변입니다
Jared Beach

13

이것은 나를 위해 잘 작동했습니다.

버튼 스타일

<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>

메모

  • 버튼은 창을 닫는 데 사용되는 것과 매우 유사한 작은 파란색 십자가를 표시합니다.
  • 그리드의 배경을 "투명"으로 설정하면 히트 테스트가 추가됩니다. 즉, 마우스가 버튼 위에 있으면 작동합니다. 이 태그를 생략하면 마우스가 아이콘의 벡터 라인 중 하나 위에있을 때만 버튼이 켜집니다 (사용하기 쉽지 않음).

1
이것은 좋은 대답입니다.하지만 Stroke마우스를 Border가져 가면 색상을 변경하는 것은 Path어떻습니까?
Nateous

1
x:Key="TransparentStyle"부분과 사용법은 제가 거기에 도달하는 데 중요했습니다 ... 감사합니다!
nrod

6

내가 사용했던 ResourceDictionary의 버튼 스타일을 공유하고 싶습니다. 스타일 트리거에서 onHover 배경을 자유롭게 변경할 수 있습니다. " ColorAnimation To = * 원하는 BG (예 : # FFCEF7A0)". 버튼 BG는 mouseOver 상태 이후 자동으로 원래 BG로 되돌아갑니다. 전환 속도를 설정할 수도 있습니다.

리소스 사전

<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

ControlTemplate을 사용하고 애니메이션 효과가있는 약간 더 어려운 답변 ( https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing- 에서 수정 됨) 제어 )

리소스 사전에서 다음과 같이 버튼에 대한 컨트롤 템플릿을 정의합니다.

<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>

도움이되기를 바랍니다.


0

버튼 스타일 변경

1 차 : 리소스 스타일 정의

<Window.Resources>

    <Style x:Key="OvergroundIn" TargetType="Button">

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="#FF16832F">
                        <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Grid Background="#FF06731F">
                                <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>

            </Trigger>
        </Style.Triggers>

    </Style>

    <Style x:Key="OvergroundOut" TargetType="Button">

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="#FFF35E5E">
                        <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Grid Background="#FFE34E4E">
                                <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>

            </Trigger>
        </Style.Triggers>

    </Style>


</Window.Resources>

2 차 정의 버튼 코드

                           <Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2"  >
                                <Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click">
                                    <Button.Content>
                                        <Grid>
                                            <TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock> 
                                        </Grid>
                                    </Button.Content>
                                </Button>
                            </Border>

세 번째 코드 뒤에

    public void ShowStatus()
    {
        switch (((MainDto)this.DataContext).State)
        {
            case State.IN:
                this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94));
                this.btnFichar.Style = Resources["OvergroundIn"] as Style;
                this.btnFichar.Content = "Fichar Salida";
                break;

            case State.OUT:
                this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83));
                this.btnFichar.Style = Resources["OvergroundOut"] as Style;
                this.btnFichar.Content = "Fichar Entrada";
                break;

        }
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.