Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set a button's inner properties in code?

Tags:

c#

button

wpf

I have an XAML button like this:

<Button x:Name="buttonOK" Content="OK" />

I have no XAML styling attached to it and no resource dictionary styling it. No external thing is styling my button and that is fine; that is how I want it.

I want, now, to change the RadiusX and RadiusY of that button in code behind, because I want a button with rounded edges. I know System.Windows.Controls.Button does not have those properties, but I know a WPF rectangle does.

I don't know if this is correct; but the WPF button control is made up of other controls? Right? Like perhaps a rectangle and a text block or label and by setting the Button.Content you're actually changing the button's inner label's content. I'm not sure how naive my thinking is there.

The bottom line is I want to do something like this:

buttonOK.InnerRectangle.RadiusX = 5;
buttonOK.InnerRectangle.RadiusY = 5;

I want it all in code, no XAML, because I have many buttons in different XAML files and I want to round their edges by calling one method in code without changing every single XAML file. Not all buttons in all my XAML files, just certain ones.

I'm already calling a single method in all my windows and user controls and I just want to add the button rounding edges styling to that method, and then it won't cause tedious code.

like image 697
Shiasu-sama Avatar asked Jul 13 '18 08:07

Shiasu-sama


1 Answers

Load XAML from a string to a Style object that allows to change the corner radius in code and then set the button style.

This is the code that worked for me:

        // OK
        private void buttonOK_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                SetButtonCornerRadiusAndTriggerStyling(buttonOK, 5);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error at 'buttonOK_Click'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // Set button corner radius and trigger styling
        public static void SetButtonCornerRadiusAndTriggerStyling(
            Button toStyle, int theCornerRadius,
            string theMouseOverBackground = "", string theMouseOverBorderBrush = "", string theMouseOverForeground = "",
            string thePressedBackground = "", string thePressedBorderBrush = "", string thePressedForeground = "",
            string theDisabledBackground = "", string theDisabledBorderBrush = "", string theDisabledForeground = "")
        {
            try
            {
                // Corner radius
                int cornerRadius = theCornerRadius;

                // Mouse over
                string defaultMouseOverBackground = "#BEE6FD";
                string defaultMouseOverBorderBrush = "#3C7FB1";
                string defaultMouseOverForeground = "Black";

                string mouseOverBackground = theMouseOverBackground;
                string mouseOverBorderBrush = theMouseOverBorderBrush;
                string mouseOverForeground = theMouseOverForeground;

                if (mouseOverBackground == null) { mouseOverBackground = ""; }
                if (mouseOverBorderBrush == null) { mouseOverBorderBrush = ""; }
                if (mouseOverForeground == null) { mouseOverForeground = ""; }

                if (mouseOverBackground.Length == 0) { mouseOverBackground = defaultMouseOverBackground; }
                if (mouseOverBorderBrush.Length == 0) { mouseOverBorderBrush = defaultMouseOverBorderBrush; }
                if (mouseOverForeground.Length == 0) { mouseOverForeground = defaultMouseOverForeground; }

                // Pressed
                string defaultPressedBackground = "#C4E5F6";
                string defaultPressedBorderBrush = "#2C628B";
                string defaultPressedForeground = "Black";

                string pressedBackground = thePressedBackground;
                string pressedBorderBrush = thePressedBorderBrush;
                string pressedForeground = thePressedForeground;

                if (pressedBackground == null) { pressedBackground = ""; }
                if (pressedBorderBrush == null) { pressedBorderBrush = ""; }
                if (pressedForeground == null) { pressedForeground = ""; }

                if (pressedBackground.Length == 0) { pressedBackground = defaultPressedBackground; }
                if (pressedBorderBrush.Length == 0) { pressedBorderBrush = defaultPressedBorderBrush; }
                if (pressedForeground.Length == 0) { pressedForeground = defaultPressedForeground; }

                // Disabled
                string defaultDisabledBackground = "#F4F4F4";
                string defaultDisabledBorderBrush = "#ADB2B5";
                string defaultDisabledForeground = "#83838C";

                string disabledBackground = theDisabledBackground;
                string disabledBorderBrush = theDisabledBorderBrush;
                string disabledForeground = theDisabledForeground;

                if (disabledBackground == null) { disabledBackground = ""; }
                if (disabledBorderBrush == null) { disabledBorderBrush = ""; }
                if (disabledForeground == null) { disabledForeground = ""; }

                if (disabledBackground.Length == 0) { disabledBackground = defaultDisabledBackground; }
                if (disabledBorderBrush.Length == 0) { disabledBorderBrush = defaultDisabledBorderBrush; }
                if (disabledForeground.Length == 0) { disabledForeground = defaultDisabledForeground; }

                string mainButtonStyleXAML = @"<Style xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' TargetType=""Button"">


    <Setter Property=""Template"">
        <Setter.Value>
            <ControlTemplate TargetType=""ButtonBase"">
                <Border
                    BorderThickness=""{TemplateBinding Border.BorderThickness}""
                    BorderBrush=""{TemplateBinding Border.BorderBrush}""
                    Background=""{TemplateBinding Panel.Background}""
                    Name=""BorderMain""
                    CornerRadius=""{CornerRadius}""
                    SnapsToDevicePixels=""True"">

                    <ContentPresenter
                        RecognizesAccessKey=""True""
                        Content=""{TemplateBinding ContentControl.Content}""
                        ContentTemplate=""{TemplateBinding ContentControl.ContentTemplate}""
                        ContentStringFormat=""{TemplateBinding ContentControl.ContentStringFormat}""
                        Name=""ContentPresenterMain""
                        Margin=""{TemplateBinding Control.Padding}""
                        HorizontalAlignment=""{TemplateBinding Control.HorizontalContentAlignment}""
                        VerticalAlignment=""{TemplateBinding Control.VerticalContentAlignment}""
                        SnapsToDevicePixels=""{TemplateBinding UIElement.SnapsToDevicePixels}""
                        Focusable=""False"" />
                </Border>

            <ControlTemplate.Triggers>

                <!-- Default -->
                <Trigger Property=""Button.IsDefaulted"" Value=""True"">
                    <Setter Property=""Border.BorderBrush"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <DynamicResource
                                ResourceKey=""{x:Static SystemColors.HighlightBrushKey}"" />
                        </Setter.Value>
                    </Setter>
                </Trigger>

                <!-- Mouse Over -->
                <Trigger Property=""UIElement.IsMouseOver"" Value=""True"">
                    <Setter Property=""Panel.Background"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <SolidColorBrush>{MouseOverBackground}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property=""Border.BorderBrush"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <SolidColorBrush>{MouseOverBorderBrush}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property=""TextElement.Foreground"" TargetName=""ContentPresenterMain"">
                        <Setter.Value>
                            <SolidColorBrush>{MouseOverForeground}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                </Trigger>

                <!-- Pressed -->
                <Trigger Property=""ButtonBase.IsPressed"" Value=""True"">
                    <Setter Property=""Panel.Background"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <SolidColorBrush>{PressedBackground}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property=""Border.BorderBrush"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <SolidColorBrush>{PressedBorderBrush}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property=""TextElement.Foreground"" TargetName=""ContentPresenterMain"">
                        <Setter.Value>
                            <SolidColorBrush>{PressedForeground}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                </Trigger>

                <!-- Disabled -->
                <Trigger Property=""UIElement.IsEnabled"" Value=""False"">
                    <Setter Property=""Panel.Background"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <SolidColorBrush>{DisabledBackground}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property=""Border.BorderBrush"" TargetName=""BorderMain"">
                        <Setter.Value>
                            <SolidColorBrush>{DisabledBorderBrush}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property=""TextElement.Foreground"" TargetName=""ContentPresenterMain"">
                        <Setter.Value>
                            <SolidColorBrush>{DisabledForeground}</SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                </Trigger>

            </ControlTemplate.Triggers>

            </ControlTemplate>
        </Setter.Value>
    </Setter>

</Style>";



                // Replace values
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{CornerRadius}", cornerRadius.ToString());

                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{MouseOverBackground}", mouseOverBackground);
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{MouseOverBorderBrush}", mouseOverBorderBrush);
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{MouseOverForeground}", mouseOverForeground);

                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{PressedBackground}", pressedBackground);
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{PressedBorderBrush}", pressedBorderBrush);
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{PressedForeground}", pressedForeground);

                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{DisabledBackground}", disabledBackground);
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{DisabledBorderBrush}", disabledBorderBrush);
                mainButtonStyleXAML = mainButtonStyleXAML.Replace("{DisabledForeground}", disabledForeground);

                StringReader mainButtonStyleXAMLStringReader = new StringReader(mainButtonStyleXAML);
                XmlReader mainButtonStyleXAMLXMLReader = XmlReader.Create(mainButtonStyleXAMLStringReader);
                Style mainButtonStyle = (Style)XamlReader.Load(mainButtonStyleXAMLXMLReader);

                toStyle.Style = mainButtonStyle;
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "Error at 'SetButtonCornerRadiusAndTriggerStyling'" +
                        Environment.NewLine + Environment.NewLine +
                        ex.Message,
                    "Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
            }
        }

So I had to put XAML in code, because FrameworkElementFactory is apparently deprecated.

MSDN:

https://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory(v=vs.110).aspx

Under remarks:

"This class is a deprecated way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate; not all of the template functionality is available when you create a template using this class. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class."

like image 80
Shiasu-sama Avatar answered Nov 01 '22 21:11

Shiasu-sama