Search code examples
winrt-xamlc++-winrt

How to construct Windows::UI::Xaml::Style class programmatically


I'm trying to programmatically construct a winrt::Windows::UI::Xaml::Style object for all buttons. But, some of the style Setter doesn't work I expect.

In summary, Setters for BorderThickness, BorderBrush, Foreground and Margin properties doesn't work. On the other hand, Setters for FontSize and Background properties work right. How can I correct this matter.

a Style object is constructed like this code.

void MainPage::SetStylePropertySetters()
{
    coloredButtonStyle.Setters().Append(Setter{ // doesn't work
        Control::BorderThicknessProperty(),
        box_value(ThicknessHelper::FromUniformLength(10.5)) });

    coloredButtonStyle.Setters().Append(Setter{ // doesn't work
        Control::BorderBrushProperty(),
        box_value(Colors::Black()) });

    coloredButtonStyle.Setters().Append(Setter{ // works right
        Control::FontSizeProperty(),
        box_value(50) });

    coloredButtonStyle.Setters().Append(Setter{ // doesn't work
        Control::ForegroundProperty(),
        box_value(Colors::White()) });

    coloredButtonStyle.Setters().Append(Setter{ // doesn't work
        FrameworkElement::MarginProperty(),
        box_value(ThicknessHelper::FromLengths(10, 10, 0, 0)) });

    coloredButtonStyle.Setters().Append(Setter{ // works right
        Control::BackgroundProperty(),
        GenerateGradient() });
}

LinearGradientBrush MainPage::GenerateGradient()
{
    GradientStopCollection gradientStopCollection{};

    GradientStop gs1;
    gs1.Color(Colors::Yellow());
    gs1.Offset(0);
    gradientStopCollection.Append(gs1);

    GradientStop gs2;
    gs2.Color(Colors::Orange());
    gs2.Offset(0.5);
    gradientStopCollection.Append(gs2);

    GradientStop gs3;
    gs3.Color(Colors::Red());
    gs3.Offset(1.0);
    gradientStopCollection.Append(gs3);

    return LinearGradientBrush(gradientStopCollection, 0.0);
}

Then the style is applied to a button in the constructor of the MainPage.

MainPage::MainPage() :
    coloredButtonStyle{ xaml_typename<Button>() }
{
    InitializeComponent();

    // Apply a style to a button named DefaultButton
    SetStylePropertySetters();
    DefaultButton().Style(coloredButtonStyle);
}

The main page has one button named DefaultButton.

<Page
    x:Class="HeadedAppDesign.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HeadedAppDesign"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel>
        <Button x:Name="DefaultButton" Content="Button"/>
    </StackPanel>
</Page>

This produces the following result:

Rendered output


Solution

  • For Thickness type properties, pass string object as the same format in XAML markup. And for Brush type properties, pass one of the derived class object of Brush class.

    void MainPage::SetStylePropertySetters()
    {
        coloredButtonStyle.Setters().Append(Setter{
            Control::BorderThicknessProperty(),
            box_value(L"10.5") });
    
        coloredButtonStyle.Setters().Append(Setter{
            Control::BorderBrushProperty(),
            SolidColorBrush(Colors::Black()) });
    
        coloredButtonStyle.Setters().Append(Setter{
            Control::FontSizeProperty(),
            box_value(50) });
    
        coloredButtonStyle.Setters().Append(Setter{
            Control::ForegroundProperty(),
            SolidColorBrush(Colors::White()) });
    
        coloredButtonStyle.Setters().Append(Setter{
            FrameworkElement::MarginProperty(),
            box_value(L"10, 10, 0, 0") });
    
        coloredButtonStyle.Setters().Append(Setter{
            Control::BackgroundProperty(),
            GenerateGradient() });
    }
    

    The margin, border width and color, font size and color and background gradient of the button all applied as I expected.

    result