[WPF] Button - zmiana koloru po najechaniu

0

Witam szanowni forumowicze.
Na samym początku zrobiłem standardowo jak dla buttonow z Form.

       button.MouseEnter += new MouseEventHandler(PrzyciskiMouseEnter); 
       private void PrzyciskiMouseEnter(object sender, EventArgs e)
        {
            (sender as Button).Background = Brushes.Black;
        } 

Bardzo się zdziwiłem widząc, że owy kod nie działa tutaj, gdyż jak przejeżdżam dalej w przycisk myszką, to zmienia na kolor niebieski, standardowy dla przycisków najechanych.
A więc napisałem klasę dziedziczącą po Button i dalej:

            protected override void OnMouseEnter(MouseEventArgs e)
            {
                base.OnMouseEnter(e);
                (e.Source as Button).Background = Brushes.Black;
            } 

Działo się tak jak wyżej. To dopisałem coś takiego.

 
           protected override void OnMouseMove(MouseEventArgs e)
            {
                base.OnMouseMove(e);
                (e.Source as Button).Background = Brushes.Black;
            } 

Lecz ta metoda tworzy błąd Object reference not set to an instance of an object. po wjechaniu na button, jakby z innej jeszcze metody coś chciało dostać się do buttona i go przekolorować.
Na pewno mieliście ten sam problem i go rozwiązaliście także byłbym szczęśliwy gdyby ktoś potrafił mnie naprowadzić na rozwiązanie tego problemu. Najdziwniejsze jest to, że dla przycisku z Form działa bez zarzutu.

//edit
Rozwiązanie jest najprawdopodobniej tutaj:
http://www.netframeworkdev.com/windows-presentation-foundation-wpf/changing-a-button-color-on-mouseenter-in-wpf-87283.shtml
ale niestety nie umiem przełożyć go z XAML do C#

1

Nie musisz do tego używać kodu.

<Window x:Class="WPFLearn.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="MyMouseOverColor">
            <Style.Triggers>
                <Trigger Property="Control.IsMouseOver" Value="True">
                    <Setter Property="Button.Background" Value="Black" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <Button Content="Hello world!" Style="{ StaticResource MyMouseOverColor}"></Button>
    </StackPanel>
</Window>
0

Deti ja wiem, że nie muszę, ale jednak było by lepiej.
Ten przycisk z WPF adaptuje na WForm przez ElementHost, i do tego kliknięcie przycisku ma wyzwolić metodę, która jest już napisana w C#. Niestety ale XAML nie znam na tyle, by ten kod wyżej wrzucić do pliku XAML, aby chodził. Bo proste skopiowanie i dopisanie niestety nie działa, gdyż tutaj dopisujesz Style do jednego buttonu tworzonego w XAML, a ja już ten button mam w C# stworzonym i do niego chciałbym się dopiąć. I do tego, co zrobić gdybym takich przycisków miał chociażby 20?

Spróbowałem chałupniczo tak przepisać do C#:

            Setter setter = new Setter();
            setter.Property = Button.BackgroundProperty;
            setter.Value = Brushes.Blue;
            Trigger tr = new Trigger();
            tr.Property = Control.IsMouseOverProperty;
            tr.Setters.Add(setter);
            Style st = new System.Windows.Style();
            st.Triggers.Add(tr);
            //bt.Style = st; 

Ale w zakomentarzowanej linii wywala z błędem '{DependencyProperty.UnsetValue}' is not a valid value for property 'IsMouseOver'.

0

Nikt nie ma pomysłu jak zmienić kod z XAML na C#? Już 2 dzień próbuję i szukam, ale jak na razie to na nic.

1

Wsadź kod stylu, który podał Deti np. do App.xaml. Powinno to tak wyglądać:

 <Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style x:Key="MyMouseOverColor">
            <Style.Triggers>
                <Trigger Property="Control.IsMouseOver" Value="True">
                    <Setter Property="Button.Background" Value="Black" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Application.Resources>
</Application>

Potem w C# pobierz referencję do tego stylu i dodaj do buttona. Powinno to tak wyglądać:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Style style = this.FindResource("MyMouseOverColor") as Style;
            this.button1.Style = style;
        }
    } 
0

Zadziałało, lecz jednak tak jak w przypadku MouseEnter. Na samym początku przycisk robi się czarny, a później zmienia kolor na standardowy dwukolorowy niebieski. I co teraz z tym fantem zrobić?

ed.1
Znalazłem taki kod:

      <Style x:Key="PlusButton" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <Border Name="Border" Padding="2" Margin="-8,3,0,0" Width="80" Height="80" BorderBrush="Black" BorderThickness="1,2,2,1"
                                        CornerRadius="0,10,0,0" Background="Yellow"  Panel.ZIndex="0"></Border>
                            <Line X1="3" Y1="12" X2="13" Y2="12"  Stroke="Black" StrokeThickness="3" />
                            <Line X1="8" Y1="7" X2="8" Y2="17"  Stroke="Black" StrokeThickness="3" />
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver"  Value="True">
                                <Setter TargetName="Border" Property="Background" Value="Green"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="False">
                                <Setter TargetName="Border" Property="Background" Value="Yellow"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>                   
                </Setter.Value>
               
            </Setter>
        </Style> 

Przycisk z tym stylem zmienia swój wygląd na ten co pomiędzy <Grid> </Grid>, ale po najechaniu poprawnie zmienia swój kolor, a nie jedynie miga. Ma ktoś może pomysł jak przerobić ten styl, aby nie zmieniał wyglądu buttona do którego będzie przypisany, a zmieniał tylko triggera?

ed.2
Przepisałem to do C#, jednak po czymś takim button znika, widocznie brakuje mu tego Grida, który jest w kodzie wyżej.

            Setter setter = new Setter();
            setter.Property = Button.BackgroundProperty;
            setter.Value = Brushes.Blue;
            Trigger tr = new Trigger();
            tr.Value = true;
            tr.Property = Control.IsMouseOverProperty;
            tr.Setters.Add(setter);
            ControlTemplate ct = new ControlTemplate();
            ct.Triggers.Add(tr);
            button.Template=ct;

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.