Jak usunąć domyślny efekt myszy na przyciskach WPF?

85

Mój problem polega na tym, że w WPF za każdym razem, gdy próbuję zmienić kolor tła przycisku za pomocą wyzwalaczy lub animacji, domyślny efekt najechania myszą (szare z pomarańczową poświatą) wydaje się mieć priorytet.

Po obszernych poszukiwaniach nie mam pojęcia, jak usunąć ten efekt.

Nellius
źródło

Odpowiedzi:

17

Musisz utworzyć własny niestandardowy szablon przycisku, aby mieć pełną kontrolę nad wyglądem we wszystkich stanach. Oto samouczek .

Mark Heath
źródło
2
Dzięki, to było idealne. Było to bardziej skomplikowane, niż się spodziewałem, ale teraz wszystko działa dobrze.
Nellius
18
Z jakiegoś powodu istnieje 100 odpowiedzi na temat tworzenia niestandardowych szablonów dla formantów WPF i wszystkie są niepotrzebnie błędne. Nie ma powodu, aby zmagać się z napisaniem 50 linii kodu szablonu dla przycisku, aby zmienić jedną rzecz. Wszystko, co musisz zrobić, to kliknąć prawym przyciskiem myszy kontrolkę w projektancie XAML i utworzyć kopię kodu szablonu. VS utworzy styl z tego właśnie przycisku i możesz go tam dostosować. Zajmuje dosłownie 2 sekundy.
The Muffin Man
@TheMuffinMan Fantastycznie, ale czy wydaje Ci się to nawet trochę dziwne, że potrzeba 50 linii kodu szablonu, aby zatrzymać przycisk przed zmianą koloru tła po najechaniu myszą? Co za głupio, zbyt skomplikowany framework WPF.
Ash
@Ash Albo ktoś mógłby argumentować, że prowadzi użytkownika w kierunku, w którym powinni podążać . Jeśli masz przycisk, który wymaga nowego stanu najechania, prawdopodobnie jest to nowy TYP przycisku; być może przycisk nawigacyjny, przycisk w zasobniku itp. Jeśli tak, nie powinieneś modyfikować dla niego jednorazowych właściwości, powinien on mieć własną kontrolkę lub grupę stylów. I właśnie to sprawia, że ​​robisz.
Matt Kenefick
108

Jest to podobne do rozwiązania, o którym wspomniał Mark Heath, ale nie zawiera tak dużej ilości kodu, aby po prostu utworzyć bardzo prosty przycisk, bez wbudowanego efektu animacji myszy nad przyciskiem. Zachowuje efekt prostego najechania kursorem myszy na pokazanie ramki przycisku na czarno.

Styl można wstawić na przykład do sekcji Window.Resources lub UserControl.Resources (jak pokazano).

<UserControl.Resources>
    <!-- This style is used for buttons, to remove the WPF default 'animated' mouse over effect -->
    <Style x:Key="MyButtonStyle" TargetType="Button">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border Name="border" 
                        BorderThickness="1"
                        Padding="4,2" 
                        BorderBrush="DarkGray" 
                        CornerRadius="3" 
                        Background="{TemplateBinding Background}">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="border" Property="BorderBrush" Value="Black" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<!-- usage in xaml -->
<Button Style="{StaticResource MyButtonStyle}">Hello!</Button>
dodgy_coder
źródło
2
To rozwiązanie bardzo mi się podoba. Jednak wyzwalacze myszy nad przyciskiem aktywują się tylko wtedy, gdy wskaźnik myszy znajduje się nad tekstem na przycisku. Dodałem blok tekstowy o określonej szerokości wewnątrz przycisku, aby naprawić ten problem.
Dave,
Pan jest świętym.
krobelusmeetsyndra
25

Wystarczy dodać bardzo proste rozwiązanie, które było dla mnie wystarczająco dobre i myślę, że rozwiązuje problem OP. Użyłem rozwiązania w tej odpowiedzi, z wyjątkiem zwykłej Backgroundwartości zamiast obrazu.

<Style x:Key="SomeButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Brak ponownego tworzenia szablonów poza wymuszeniem, Backgroundaby zawsze był Transparenttłem z przycisku szablonu - po wykonaniu tej czynności najechanie myszą nie wpływa już na tło. Oczywiście zastąp Transparentdowolną preferowaną wartością.

Lyall
źródło
10

Muffin Man miał bardzo prostą odpowiedź, która działała dla mnie.

Aby dodać trochę bardziej szczegółowy kierunek, przynajmniej dla VS 2013:

  • Kliknij prawym przyciskiem myszy kontrolkę
  • Wybierz Edytuj szablon => Edytuj kopię ...
  • Wybrałem opcję „Aplikacja”, aby zapisać styl
    • Tutaj możesz bezpośrednio edytować plik App.xaml i wyświetlać intuicyjnie nazwane właściwości. Dla moich celów po prostu ustawiłem RenderMouseOver = "False"
  • Następnie w pliku MainWindow.xaml lub gdziekolwiek jest twój GUI, możesz wkleić nowy styl na końcu tagu Button, np. ... Style="{DynamicResource MouseOverNonDefault}"/>
Benji-Man
źródło
Kim jest Muffin Man?
Mike W
LOL. Udzielił drugiej odpowiedzi na pytanie zaakceptowane przez właściciela. Nie byłem pewien, czy pytasz poważnie, czy żartujesz. Trudno powiedzieć, mając imię takie jak Muffin Man.
Benji-Man
5

Ten link bardzo mi pomógł http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/

Zdefiniuj styl w UserControl.Resources lub Window.Resources

 <Window.Resources>
        <Style x:Key="MyButton" TargetType="Button">
            <Setter Property="OverridesDefaultStyle" Value="True" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Opacity" Value="0.8" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

Następnie dodaj styl do swojego przycisku w ten sposób Style = "{StaticResource MyButton}"

<Button Name="btnSecond" Width="350" Height="120" Margin="15" Style="{StaticResource MyButton}">
    <Button.Background>
        <ImageBrush ImageSource="/Remove_Default_Button_Effect;component/Images/WithStyle.jpg"></ImageBrush>
    </Button.Background>
</Button>
Arash.Zandi
źródło
4

Jeśli ktoś nie chce zastąpić domyślnego szablonu sterowania, oto rozwiązanie.

Możesz utworzyć DataTemplate dla przycisku, który może mieć TextBlock, a następnie możesz napisać wyzwalacz Property we właściwości IsMouseOver, aby wyłączyć efekt myszy. Wysokość TextBlock i Button powinna być taka sama.

<Button Background="Black" Margin="0" Padding="0" BorderThickness="0" Cursor="Hand" Height="20">
    <Button.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="GO" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" TextDecorations="Underline" Margin="0" Padding="0" Height="20">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Style.Triggers>
                            <Trigger Property ="IsMouseOver" Value="True">
                                <Setter Property= "Background" Value="Black"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </Button.ContentTemplate>
</Button>
Prateek Rai
źródło
1

Rozszerzenie odpowiedzi dodgy_coder, które dodaje obsługę ...

  • Utrzymywanie stylu przycisku WPF
  • Dodaje obsługę IsSelected i hover, czyli przełączany przycisk

        <Style x:Key="Button.Hoverless" TargetType="{x:Type ButtonBase}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ButtonBase}">
                        <Border Name="border"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Padding="{TemplateBinding Padding}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True" />
                                    <Condition Property="Selector.IsSelected" Value="False" />
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="#FFBEE6FD" />
                            </MultiTrigger>
    
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True" />
                                    <Condition Property="Selector.IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="#BB90EE90" />
                            </MultiTrigger>
    
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="False" />
                                    <Condition Property="Selector.IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="LightGreen" />
                            </MultiTrigger>
    
                            <Trigger Property="IsPressed" Value="True">
                                <Setter TargetName="border" Property="Opacity" Value="0.95" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

przykłady ..

<Button Content="Wipe On" Selector.IsSelected="True" /> <Button Content="Wipe Off" Selector.IsSelected="False" />

stoj
źródło
0

Korzystanie z wyzwalacza szablonu:

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="White"></Setter>
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="White"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Laine Mikael
źródło