Bagaimana Anda mengubah Latar Belakang untuk Tombol MouseOver di WPF?

93

Saya memiliki tombol di halaman saya dengan XAML ini:

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

Tetapi ketika saya meletakkan mouse di atas tombol saya, latar belakang tombol berubah menjadi latar belakang abu-abu jendela default.
Apa masalahnya?

Ini adalah gambar tombol sebelum dan sesudah gerakan mouse:
Sebelum:
Sebelum
Sesudah:
Setelah

Sepehr Mohammadi
sumber
Tetapi Anda harus memulai gambar Forward-48.pngdan memicu IsMouseOver untuk mengubahnya untuk hal yang sama Forward-48.png. Saya mencoba menggunakan kode Anda dengan gambar yang berbeda dan semuanya bekerja dengan baik.
Anatoliy Nikolaev
1
@anatoliy: Tidak Berhasil.
Sepehr Mohammadi
Setelah itu warna default Anda? Di mana lagi Anda tidak mengubah / tidak mengatur latar belakang tombol? Saya memiliki kode Anda berfungsi dengan baik.
Anatoliy Nikolaev

Jawaban:

174

Untuk menghapus MouseOverperilaku default di ButtonAnda perlu mengubah ControlTemplate. Mengubah Styledefinisi Anda menjadi berikut ini akan berhasil:

<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: Ini terlambat beberapa tahun, tetapi Anda sebenarnya dapat mengatur sikat perbatasan di dalam perbatasan yang ada di sana. Idk jika itu ditunjukkan tetapi sepertinya itu tidak ...

Richard E.
sumber
1
Ini berfungsi, namun tombol Perbatasan akan lenyap! Harus meletakkan elemen <Border BorderBrush = "DarkGray" BorderThickness = "1"> di sekitar tombol.
Venugopal M
4
@CF alasannya adalah gaya Tombol standar memiliki pemicu di dalam ControlTemplate, sehingga mereka menggantikan Stylepemicu OP .
torvin
1
@torvin Itu sepertinya sangat mundur! Mengapa pemicu yang ditentukan pengguna harus diganti secara default? Saya memahami hierarkinya, ControlTemplate berada di atas Style, tetapi saya tidak mengerti mengapa sangat sulit untuk mengganti pengaturan dasar seperti ini.
Fuselight
@Fuselight, pemicu di dalam ControlTemplatepada dasarnya bertuliskan 'Cat perbatasan sesuai dengan Backgroundwarna. Dan jika mouse berada di atas tombol - cat yang membatasi warna ini sebagai gantinya ', sedangkan dalam gaya Anda hanya memiliki akses ke Backgroundwarna, dan bukan ke warna tepi yang mendasarinya. Saya mengerti maksud Anda, gaya WPF meninggalkan banyak hal yang diinginkan ...
torvin
Ini memiliki manfaat tambahan untuk menghapus kotak biru yang muncul saat terkena gerakan mouse, saat menggunakan gambar dengan latar belakang transparan. Dalam kasus saya, saya tidak menginginkan perbatasan, jadi setel BorderThickness ke 0.
Chuck Savage
22

Semua jawaban sejauh ini melibatkan penggantian sepenuhnya perilaku tombol default dengan yang lain. Namun, IMHO berguna dan penting untuk dipahami bahwa mungkin saja mengubah hanya bagian yang Anda pedulikan , dengan mengedit template default yang ada untuk elemen XAML.

Dalam kasus menangani efek hover pada tombol WPF, perubahan tampilan dalam Buttonelemen WPF disebabkan oleh Triggergaya default untuk Button, yang didasarkan pada IsMouseOverproperti dan menyetel properti Backgrounddan BorderBrushdari Borderelemen tingkat atas di template kontrol. The Buttonlatar belakang elemen adalah di bawah Borderlatar belakang elemen, sehingga mengubah Button.Backgroundproperti tidak mencegah efek hover dari yang terlihat.

Dengan sedikit usaha, Anda dapat menimpa perilaku ini dengan penyetel Anda sendiri, tetapi karena elemen yang perlu Anda pengaruhi ada di templat dan tidak langsung dapat diakses di XAML Anda sendiri, pendekatan itu akan sulit dan IMHO terlalu rumit.

Pilihan lain adalah menggunakan grafik sebagai Contentuntuk Buttondaripada Background. Jika Anda membutuhkan konten tambahan di atas grafik, Anda dapat menggabungkannya dengan a Gridsebagai objek tingkat atas dalam konten.

Namun, jika Anda benar-benar hanya ingin menonaktifkan efek hover sepenuhnya (bukan hanya menyembunyikannya), Anda dapat menggunakan Visual Studio XAML Designer:

  1. Saat mengedit XAML Anda, pilih tab "Desain" .
  2. Pada tab "Design" , cari tombol yang ingin Anda nonaktifkan efeknya.
  3. Klik kanan tombol itu, dan pilih "Edit Template / Edit Salinan ..." . Pilih di prompt yang Anda tuju di mana Anda ingin sumber daya template baru ditempatkan. Ini akan tampak tidak melakukan apa-apa, tetapi pada kenyataannya Perancang akan menambahkan sumber daya baru di mana Anda memberi tahu, dan mengubah elemen tombol Anda untuk merujuk gaya yang menggunakan sumber daya tersebut sebagai templat tombol.
  4. Sekarang, Anda bisa mengedit gaya itu. Hal termudah adalah menghapus atau mengomentari (mis. Ctrl+ E, C) <Trigger Property="IsMouseOver" Value="true">...</Trigger>Elemen. Tentu saja, Anda dapat membuat perubahan apa pun pada template yang Anda inginkan pada saat itu.

Setelah selesai, gaya tombol akan terlihat seperti ini:

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

(Catatan: Anda dapat menghilangkan p:kualifikasi namespace XML dalam kode sebenarnya ... Saya menyediakannya di sini hanya karena pemformat kode XML Stack Overflow menjadi bingung oleh <Style/>elemen yang tidak memiliki nama yang sepenuhnya memenuhi syarat dengan namespace XML.)

Jika Anda ingin menerapkan gaya yang sama ke tombol lain, Anda dapat mengklik kanan tombol tersebut dan memilih "Edit Template / Terapkan Sumber Daya" dan pilih gaya yang baru saja Anda tambahkan untuk tombol pertama. Anda bahkan dapat menjadikan gaya tersebut sebagai gaya default untuk semua tombol, menggunakan teknik normal untuk menerapkan gaya default ke elemen di XAML.

Peter Duniho
sumber
6
Terima kasih banyak. Ini adalah satu-satunya jawaban yang dapat ditoleransi di sini
Pantai Jared
13

Ini bekerja dengan baik untuk saya.

Gaya Tombol

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

Tombol

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

Catatan

  • Tombol tersebut menampilkan tanda silang biru kecil, seperti yang digunakan untuk menutup jendela.
  • Dengan menyetel latar belakang kisi ke "Transparan", ini menambahkan hittest, yang berarti jika mouse ada di mana saja di atas tombol, maka itu akan berfungsi. Abaikan tag ini, dan tombol hanya akan menyala jika mouse berada di atas salah satu garis vektor di ikon (ini sangat tidak berguna).
Contango
sumber
1
Ini adalah jawaban yang bagus, tapi bagaimana dengan mengubah Strokewarna di hover dari Borderjuga, tanpa itu hanya di hover Path?
Nateous
1
x:Key="TransparentStyle"Bagian ini dan penggunaannya penting bagi saya untuk sampai di sana ... Terima kasih!
Nrod
6

Hanya ingin membagikan gaya tombol saya dari ResourceDictionary saya yang telah saya gunakan. Anda dapat dengan bebas mengubah latar belakang onHover pada pemicu gaya. " ColorAnimation To = * BG yang Anda inginkan (yaitu # FFCEF7A0)". Tombol BG juga akan secara otomatis kembali ke BG aslinya setelah status mouseOver. Anda bahkan dapat mengatur seberapa cepat transisi.

Kamus Sumber Daya

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

yang harus Anda lakukan hanyalah memanggil gaya.

Implementasi Contoh

<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">  
     <StackPanel>
     <TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
     </StackPanel>
</Button>
Justin Adrias
sumber
3

Jawaban yang sedikit lebih sulit yang menggunakan ControlTemplate dan memiliki efek animasi (diadaptasi dari https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing- kendali )

Dalam kamus sumber daya Anda, tentukan templat kontrol untuk tombol Anda seperti ini:

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

di XAML Anda, Anda dapat menggunakan template di atas untuk tombol Anda seperti di bawah ini:

Tentukan tombol Anda

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

Semoga membantu

Iakobos Karakizas
sumber
0

Untuk mengubah gaya tombol

Pertama: tentukan gaya sumber daya

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

Kedua, tentukan kode tombol

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

Kode 3 di belakang

    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;

        }
    }
Ángel Ibáñez
sumber