4

I am trying to create a button Style that I can use for a "Lookup" button throughout my UWP app. However, the icon only appears on the first button on the screen. I tried this solution using templates, but it is not working for me. Thanks for the help.

Code:

<Page.Resources>
    <ControlTemplate x:Key="FindSymbolTemplate">
        <SymbolIcon Symbol="Find" Foreground="White" />
    </ControlTemplate>
    <Style TargetType="Button" x:Key="LookupButton">
        <Setter Property="Content">
            <Setter.Value>
                <ContentControl Template="{StaticResource FindSymbolTemplate}" />
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>
....
<Button x:Name="tourNumLookup"
       Style="{StaticResource LookupButton}"
       Grid.Column="1"
       Margin="10,0"
       VerticalAlignment="Center" />
....
<Button x:Name="customerIdLookup"
       Style="{StaticResource LookupButton}"
       VerticalAlignment="Center"
       Grid.Column="1"
       Grid.Row="1"
       Margin="10,0" />

The two buttons in the UI. Only the first has the SymbolIcon content.

enter image description here

Community
  • 1
  • 1
NSouth
  • 5,067
  • 7
  • 48
  • 83

3 Answers3

3

@Romasz's solution absolutely works, but what if you want a lightly different Foreground on the SymbolIcon inside another Button?

Here's a potentially more flexible way that I normally go with.

First let's create a base Style that holds some default values for all the icons.

<Style x:Key="Style-Icon-Base"
       TargetType="ContentControl">
    <!-- If you don't specify the Foreground, it will use its ancestor's -->
    <!--<Setter Property="Foreground"
            Value="White" />-->
    <Setter Property="HorizontalContentAlignment"
            Value="Center" />
    <Setter Property="VerticalContentAlignment"
            Value="Center" />
    <Setter Property="Width"
            Value="20" />
    <Setter Property="Height"
            Value="20" />
    <Setter Property="Padding"
            Value="0" />
</Style>

Then we create a new icon Style which inherits from the one above. Note within the ControlTemplate I have used TemplateBinding to make property values dynamic. TemplateBinding isn't available inside a DataTemplate.

<Style x:Key="Style-Icon-Find"
       BasedOn="{StaticResource Style-Icon-Base}"
       TargetType="ContentControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                <!-- 
                    'cause you cannot change the size of the SymbolIcon, we insert a Viewbox here, 
                    otherwise you don't need it. 
                -->
                <Viewbox Margin="{TemplateBinding Padding}"
                         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                         VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                    <SymbolIcon Symbol="Find"
                                Foreground="{TemplateBinding Foreground}" />
                </Viewbox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

This way you have created a highly reusable icon Style, to use it, have a look at the following Buttons:

<StackPanel Orientation="Horizontal"
            HorizontalAlignment="Center">
    <Button Margin="4"
            Padding="8"
            BorderBrush="LightBlue">
        <ContentControl Width="36"
                        Height="36"
                        Foreground="DarkCyan"
                        Style="{StaticResource Style-Icon-Find}" />
    </Button>

    <!-- Note how I defined the Foreground at the Button level and it flows down to the icon -->
    <Button Foreground="DarkGoldenrod"
            Margin="4">
        <StackPanel Orientation="Horizontal">
            <ContentControl Style="{StaticResource Style-Icon-Find}"
                            Width="16"
                            Height="16" />
            <TextBlock Text="Search"
                       VerticalAlignment="Center"
                       Margin="8,0,0,0" />
        </StackPanel>
    </Button>

    <Button Margin="4"
            Padding="4">
        <ContentControl Style="{StaticResource Style-Icon-Find}" />
    </Button>
</StackPanel>

And they look like:

enter image description here

Justin XL
  • 38,763
  • 7
  • 88
  • 133
2

Generally UI elements can be used once (or saying different - have only one parent) - this is probably why it only works for the first button in your case. One solution may be to define DataTemplate and use it as ContentTemplate, so each button creates its own icon:

<Page.Resources>
    <DataTemplate x:Key="FindTemplate">
        <SymbolIcon Symbol="Find" Foreground="White" />
    </DataTemplate>
</Page.Resources>
...
<Button x:Name="tourNumLookup" ContentTemplate="{StaticResource FindTemplate}"
        Grid.Column="1" Margin="10,0" VerticalAlignment="Center" />
<Button x:Name="customerIdLookup" ContentTemplate="{StaticResource FindTemplate}"
        VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" Margin="10,0" />
Romasz
  • 29,662
  • 13
  • 79
  • 154
0

You don't need to create ControlTemplate to reuse the icon. You can simply put this SymbolIcon to the resource dictionary and use as StaticResource for the buttons' Content.

<Page.Resources>
    <SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
</Page.Resources>

<Button x:Name="tourNumLookup"
        Content="{StaticResource FindSymbol}"
        Grid.Column="1"
        Margin="10,0"
        VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
        Content="{StaticResource FindSymbol}"
        VerticalAlignment="Center"
        Grid.Column="1"
        Grid.Row="1"
        Margin="10,0" />

UPDATE

BTW this is possibly a bug in the UWP platform, because I tried the following code and only the first Button rendered the icon at desing time and none of the at runtime.

<Page.Resources>
    <SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
    <Style TargetType="Button" x:Key="LookupButton">
        <Setter Property="Content" Value="{StaticResource FindSymbol}"/>
    </Style>
</Page.Resources>

<StackPanel>
    <Button x:Name="tourNumLookup"
            Style="{StaticResource LookupButton}"
            Margin="10,0"
            VerticalAlignment="Center" />
    <Button x:Name="customerIdLookup"
            Style="{StaticResource LookupButton}"
            VerticalAlignment="Center"
            Margin="10,0" />
</StackPanel>

I tried to assign the Setter's Value directly but I got the same result. And also tried with FontIcon.

Tóth Tibor
  • 1,526
  • 12
  • 21
  • I, too, had issues with the code you suggested. Another user submitted a working approach as a comment on my question. Thanks for the input! – NSouth Mar 09 '17 at 20:29