Development Tip

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

yourdevel 2020. 10. 11. 11:27
반응형

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


이 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 전후의 버튼 그림입니다.
이전 :
전에
이후 :
후


기본 제거하려면 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하지만 그것이 아닌 것 같습니다 ...


지금까지의 모든 대답은 기본 버튼 동작을 다른 것으로 완전히 바꾸는 것과 관련이 있습니다. 그러나 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의 요소에 기본 스타일을 적용하는 일반적인 기술을 사용하여 해당 스타일을 모든 단추의 기본 스타일로 만들 수도 있습니다.


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

버튼 스타일

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

메모

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

내가 사용했던 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>

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>

도움이되기를 바랍니다.


버튼 스타일 변경

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;

        }
    }

참고 URL : https://stackoverflow.com/questions/17259280/how-do-you-change-background-for-a-button-mouseover-in-wpf

반응형