Search code examples
c#wpfxaml

Why is the Style not getting applied from code?


I'm trying to create a button from code and make the hover color change, for some reason the setters, etc are not getting applied. I'm pretty sure I'm either missing a step or it's something else but nothing changes, not even the color while not hovering. I'm not trying to make the button in XAML but create it in code and I know how to do it in XAML.

System.Windows.Controls.Button createPlaylist = new System.Windows.Controls.Button()
     {
        Height = 100,
        Width = 100,
        Margin = new Thickness(0,50,0,0)
    };

    //                                      STYLE END                                   //
    var dt = new DataTemplate();

    Style style = new Style(typeof(System.Windows.Controls.Button), createPlaylist.Style);

    Trigger t = new Trigger();
    t.Property = IsMouseOverProperty;
    t.Value = true;
    Setter setter = new Setter();
    setter.Property = BackgroundProperty;
    setter.Value = Brushes.Blue;
    t.Setters.Add(setter);

    Trigger s = new Trigger();
    s.Property = IsMouseOverProperty;
    s.Value = false;
    Setter set = new Setter();
    set.Property = BackgroundProperty;
    set.Value = Brushes.Red;
    s.Setters.Add(setter);

    style.Triggers.Add(t);

    createPlaylist.Style = style;

Solution

  • You have to manage the Background color of the Border within the Template of the Button, instead of just changing the Background property of the Button itself.

    i.e. do the equivalent of this XAML:

    <Style TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}">
                        <ContentPresenter/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="Blue"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    

    Something like this on code behind:

    Style buttonStyle = new Style();
    
    FrameworkElementFactory contentBorder = new FrameworkElementFactory(typeof(Border));
    contentBorder.AppendChild(new FrameworkElementFactory(typeof(ContentPresenter)));
    contentBorder.SetBinding(Border.BackgroundProperty, new Binding { RelativeSource = RelativeSource.TemplatedParent, Path = new PropertyPath(nameof(Background)) });
    ControlTemplate templateButton = new ControlTemplate(typeof(Button)) { VisualTree = contentBorder };
    buttonStyle.Setters.Add(new Setter { Property = Button.TemplateProperty, Value = templateButton });
    
    Trigger styleTrigger = new Trigger { Property = Button.IsMouseOverProperty, Value = true };
    styleTrigger.Setters.Add(new Setter { Property = Button.BackgroundProperty, Value = Brushes.Blue });
    buttonStyle.Triggers.Add(styleTrigger);
    
    createPlaylist.Style = buttonStyle;