1

I'm trying to create a style for a button, especially to change the IsMouseOver style (it must be overrided through a control template). I'm trying this code (I have to use c#, no xaml), but the button is only turning to yellow, IsMouseOver is not doing anything.

private void CreateElement(int i)
{
    UIElementOut[i] = new Button();
    var uiElement = (Button)UIElementOut[i];
    uiElement.Width = 100;
    uiElement.Height = 100;
    uiElement.VerticalAlignment = VerticalAlignment.Center;
    uiElement.HorizontalAlignment = HorizontalAlignment.Center;
    uiElement.Content = TextIn[i];
    uiElement.FontFamily = new FontFamily(FFontInput[i]);
    uiElement.FontSize = Convert.ToDouble(FontSizeIn[i]);

    Style MyButtonStyle = new Style();
    ControlTemplate templateButton = new ControlTemplate(typeof(Button));
    FrameworkElementFactory elemFactory = new FrameworkElementFactory(typeof(Button));
    elemFactory.Name = "myButton";
    elemFactory.SetValue(Button.BackgroundProperty, Brushes.Yellow);
    templateButton.VisualTree = elemFactory;
    elemFactory.AppendChild(new FrameworkElementFactory(typeof(ContentPresenter)));

    Trigger templateTrigger = new Trigger { Property = Button.IsPressedProperty, Value = true };
    templateTrigger.Setters.Add(new Setter { Property = Button.ForegroundProperty, Value = Brushes.Violet });
    templateTrigger.Setters.Add(new Setter { Property = Button.BackgroundProperty, Value = Brushes.Red });
    templateButton.Triggers.Add(templateTrigger);

    Setter setter = new Setter { TargetName = "myButton", Property = Button.TemplateProperty, Value = templateButton };
    MyButtonStyle.Setters.Add(setter);
    uiElement.Style = MyButtonStyle;
    uiElement.Template = templateButton;
}
3
  • 1
    When you say "I have to use c#, no xaml" do you really mean "I have to"? Or is it more accurate to say "I want to"? Because data binding is the correct way to do this and I can't think of a single reason why anyone would ever "have to" do it the way you're doing it. If you clarify the reason why you think you need to do it the wrong way chances are there's a good solution that avoids it entirely. Commented Sep 13, 2015 at 9:57
  • @lecloneur why do you put Button inside button template? Outer Button is not the same as inner Button nor will they be linked in any way. Also I don't see IsMouseOver behaviour. There's only IsPressed trigger. Commented Sep 13, 2015 at 10:50
  • Mark Feldman, I have to use c# because I'm programming WPF control plugin for a software called vvvv and I have absolutely no idea how I can use xaml with vvvv. That's the reason I'm using c# only here, and I know that this is definitely not the easiest way... @dkozl, when posting the code I did a mistake, you should indeed see IsMouseOver instead of IsPressed. About the inner and outer button I didn't know about that so I will search a little (I'm beginner). Thx Commented Sep 13, 2015 at 13:54

1 Answer 1

6

You seem to put Button inside button's template. This inner button is not the same as the outer button nor they will be linked in any way. Normally I would expect for example Border in that place which Background property is bound to templated parent. Its default value would be set as Style's setter and changed by Style's trigger

Style MyButtonStyle = new Style();
ControlTemplate templateButton = new ControlTemplate(typeof(Button));
FrameworkElementFactory elemFactory = new FrameworkElementFactory(typeof(Border));
elemFactory.SetBinding(Border.BackgroundProperty, new Binding { RelativeSource = RelativeSource.TemplatedParent, Path = new PropertyPath("Background") });
templateButton.VisualTree = elemFactory;
elemFactory.AppendChild(new FrameworkElementFactory(typeof(ContentPresenter)));
MyButtonStyle.Setters.Add(new Setter { Property = Button.BackgroundProperty, Value = Brushes.Yellow });
MyButtonStyle.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.ForegroundProperty, Value = Brushes.Violet });
styleTrigger.Setters.Add(new Setter { Property = Button.BackgroundProperty, Value = Brushes.Red });
MyButtonStyle.Triggers.Add(styleTrigger);

which is the equivalent of same code in XAML

<Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Yellow"/>
    <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="Red"/>
            <Setter Property="Foreground" Value="Violet"/>
        </Trigger>
    </Style.Triggers>
</Style>

However, because you change Template, which effectively makes the button look and feel, you need to be aware that your Button won't have the default Button's behaviour until you'll add it manually.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks a lot, it's working now. Didn't get the Border things at first, wasn't that obvious as I was trying to "style" a button but not a "border"...
something I don't understand now is why the content of the button is no more centered and affected by ContentAlignmentProperty ?
Like I said it's because you change Button's template therefore you completely redesign how it looks and behaves. It won't have functionality until you add it. In this case you need to bind (in the same way you do Border.Background) ContentPresenter.HorizontalAlignment to Button.HorizontalContentAlignment and analogically for vertical alignment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.