question

SteveWood-4261 avatar image
1 Vote"
SteveWood-4261 asked ·

How to Get Brush or Color that System Uses for Selected Controls?

I want to get the Brush or Color that is used in UWP applications for controls that are selected. When a control is selected by the user the system sets the background color to indicate that the control is selected and while it's possible to flash a control on the screen and set focus to it then get the background brush and color I'm hoping there's a way to get the brush or color that doesn't make it look like there's a glitch in the app. I'm also hoping that there's a way to get the other brushes and colors that are used by the system, for example the highlight brush and disabled (grayed out) brush.



Update

 <Page
   x:Class="DemoTextBlockBackground.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="using:DemoTextBlockBackground"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d"
   Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Loaded="Page_Loaded">
     
   <RelativePanel x:Name="thisRelativePanel">
     
   </RelativePanel>
  </Page>
    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
     TextBlock thisUnSelectedTextBlock = new TextBlock();
     thisUnSelectedTextBlock.Text = "thisUnSelectedTextBlock";
     Border thisUnSelectedBorder = new Border();
     thisUnSelectedBorder.Child = thisUnSelectedTextBlock;
     thisRelativePanel.Children.Add(thisUnSelectedBorder);
     
     TextBlock thisSelectedTextBlock = new TextBlock();
     thisSelectedTextBlock.Text = "thisSelectedTextBlock";
     Border thisSelectedBorder = new Border();
     thisSelectedBorder.Child = thisSelectedTextBlock;
     Brush thisSelectedBrush = (Brush)App.Current.Resources["SystemControlHighlightListAccentLowBrush"];
     thisSelectedBorder.Background = thisSelectedBrush;
     thisRelativePanel.Children.Add(thisSelectedBorder);
     RelativePanel.SetBelow(thisSelectedBorder, thisUnSelectedBorder);
     
     ListBox thisListBox = new ListBox();
     thisListBox.Items.Add("thisUnSelectedListBoxItem");
     thisListBox.Items.Add("thisSelectedListBoxItem");
     thisListBox.SelectedIndex = 1;
     thisRelativePanel.Children.Add(thisListBox);
     RelativePanel.SetBelow(thisListBox, thisSelectedBorder);
    }
windows-uwp
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

fourelem avatar image
0 Votes"
fourelem answered ·

Hello. Though I think it may be possible to achive the color seen in selected ListBoxItem's background by using SystemControlHighlightListAccentLowBrush background in a container with SystemControlBackgroundChromeMediumLowBrush background, but it's not enough?

e.g.

 <Grid>
     <Grid.RowDefinitions>
         <RowDefinition Height="Auto"/>
         <RowDefinition/>
     </Grid.RowDefinitions>
    
     <Border Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" Margin="8">
         <StackPanel Margin="4">
             <StackPanel.Resources>
                 <Style TargetType="Border">
                     <Setter Property="Margin" Value="4"/>
                     <Setter Property="Padding" Value="4"/>
                 </Style>
             </StackPanel.Resources>
             <TextBlock Margin="8">Background=SystemControlBackgroundChromeMediumLowBrush (ListBox.Background)</TextBlock>
    
             <Border Background="{ThemeResource SystemControlHighlightListAccentHighBrush}">
                 <TextBlock>SystemControlHighlightListAccentHighBrush (SelectedPressed)</TextBlock>
             </Border>
             <Border Background="{ThemeResource SystemControlHighlightListAccentLowBrush}">
                 <TextBlock>SystemControlHighlightListAccentLowBrush (Selected)</TextBlock>
             </Border>
             <Border Background="{ThemeResource SystemControlHighlightListAccentMediumBrush}">
                 <TextBlock>SystemControlHighlightListAccentMediumBrush (SelectedPointerOver)</TextBlock>
             </Border>
             <Border Background="{ThemeResource SystemControlHighlightListMediumBrush}">
                 <TextBlock>SystemControlHighlightListMediumBrush (Pressed)</TextBlock>
             </Border>
             <Border Background="{ThemeResource SystemControlHighlightListLowBrush}">
                 <TextBlock>SystemControlHighlightListLowBrush (PointerOver)</TextBlock>
             </Border>
         </StackPanel>
     </Border>
    
     <ListBox Grid.Row="1" SelectedIndex="0" Margin="8">
    
         <ListBoxItem>Hello</ListBoxItem>
         <ListBoxItem>World</ListBoxItem>
         <ListBoxItem IsEnabled="False">Disabled</ListBoxItem>
     </ListBox>
 </Grid>

Or otherwise, if you'd like to obtain the mixed color in the code behind, interpolate two brushes based on Opacity.

 public SolidColorBrush ListBoxSelectedItemBackgroundBrush
 {
     get
     {
         // Let's get SystemAccentColor with 0.4 opacity on ListBox's background color.
    
         // <SolidColorBrush x:Key="SystemControlHighlightListAccentLowBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.4" />
         var fg_brush = Resources.ThemeDictionaries["SystemControlHighlightListAccentLowBrush"] as SolidColorBrush;
    
         // <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource SystemChromeMediumLowColor}" />
         var bg_brush = Resources.ThemeDictionaries["SystemControlBackgroundChromeMediumLowBrush"] as SolidColorBrush; // #FFF2F2F2 in Light theme
    
         SolidColorBrush mixed_brush = new SolidColorBrush(Color.FromArgb(
             (byte)(bg_brush.Color.A * (1.0 - fg_brush.Opacity) + fg_brush.Color.A * fg_brush.Opacity),
             (byte)(bg_brush.Color.R * (1.0 - fg_brush.Opacity) + fg_brush.Color.R * fg_brush.Opacity),
             (byte)(bg_brush.Color.G * (1.0 - fg_brush.Opacity) + fg_brush.Color.G * fg_brush.Opacity),
             (byte)(bg_brush.Color.B * (1.0 - fg_brush.Opacity) + fg_brush.Color.B * fg_brush.Opacity)
         ));
    
         Debug.WriteLine("#{0:X2}{1:X2}{2:X2}{3:X2}",
             mixed_brush.Color.A,
             mixed_brush.Color.R,
             mixed_brush.Color.G,
             mixed_brush.Color.B
         ); // #FF91C1E7 
    
         return mixed_brush;
     }
 }
· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Yes! That's it. I thought I had the math right, and I did; However, what I didn't know was that the background used by the ListBox was SystemControlBackgroundChromeMediumLowBrush. generic.xaml has:

 <SolidColorBrush x:Key="ListBoxBackgroundThemeBrush" Color="#CCFFFFFF" />

So, I couldn't get the same resultant color of #FF91C1E7 that the ListBox was providing because that's not the background that it's using. Thank you so much!



0 Votes 0 ·
Groovykool-9087 avatar image
0 Votes"
Groovykool-9087 answered ·

Do you want to capture the colors from a live app or do just want to know which colors a specific UWP control uses in the latest version of windows?

Color is not static and depends on Theme.

Start here.
https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-theme-resources

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks...that might get me closer, but I need to get the brush or color in code at runtime i.e. C# and not XAML. And, when I try to use one of the Solid Color Brush keys I get an exception:

 thisSelectedSolidColorBrush = new SolidColorBrush("{StaticResource ListBoxItemSelectedBackgroundThemeBrush}");
 error CS1503: Argument 1: cannot convert from 'string' to 'Windows.UI.Color'

And, the resources don't appear to be available in code:

 ?this.DefaultStyleResourceUri
 null
    
 ?this.Resources.Keys.Count
 0

So, now that I know the key name of the brush that I want the question remains: How can I get the Brush or Color that System Uses for Selected Controls in C# code at runtime?





0 Votes 0 ·
RichardZhang-MSFT avatar image
0 Votes"
RichardZhang-MSFT answered ·

Hello,​

Welcome to our Microsoft Q&A platform!

Your problem is how to get the system's default brush resources.

All the default resources used by UWP are stored in the file generic.xaml. You can access this file in two ways:

1. Access via file path

Suppose the drive where you installed the Windows 10 SDK is C:\\, then the generic.xaml file path is

C:\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\{system_version}\Generic.

2. Jump through Visual Studio

Place the cursor on the default resource reference in the project (such as the Background resource referenced in the newly created Page), and press F12 to jump to the corresponding resource entry in generic.xaml.



After entering generic.xaml, we can find the default style of the required control.

Suppose we need to modify the background color of the Button when the pointer is moved over. Through generic.xaml, we know that the background color of the Button in PointerOver resource name is ButtonBackgroundPointerOver, then we can rewrite it in App.xaml.

 <Application
     ...>
     <Application.Resources>
         <SolidColorBrush x:Key="ButtonBackgroundPointerOver" Color="Red"/>
     </Application.Resources>
 </Application>

In this way, when you move the pointer into the Button, you will find that the control turns red.

Through the above method, you can find the brush resources used by almost all the controls and modify them by rewriting in the project.

But regarding the highlight brush when selecting the control, this is another problem, you can refer to this document: Reveal Focus.



Update

When you know the key name, use this method to get the corresponding brush resource:

 var brush = (Brush)Application.Current.Resources["ButtonBackgroundPointerOver"];

When you assign values to the corresponding properties of the control, pay attention to the type matching.

Thanks.




· 17 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks...placing my cursor in the following Xaml of a new page and pressing F12 got me the list of SolidColorBrush definitions:

 Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"

And, it gets me closer, but I need to get the brush or color in code at runtime i.e. C# and not XAML. And, when I try to use one of the Solid Color Brush keys I get an exception:

 thisSelectedSolidColorBrush = new SolidColorBrush("{StaticResource ListBoxItemSelectedBackgroundThemeBrush}");
 error CS1503: Argument 1: cannot convert from 'string' to 'Windows.UI.Color'

And, the resources don't appear to be available in code:

 ?this.DefaultStyleResourceUri
 null
    
 ?this.Resources.Keys.Count
 0

So, now that I know the key name of the brush that I want the question remains: How can I get the Brush or Color that System Uses for Selected Controls in C# code at runtime?






0 Votes 0 ·

Hi, I updated my answer, please check.

0 Votes 0 ·

Thanks. However, the values in the resources don't match the Brush or Color that is used for a Selected ListBoxItem.

Using a screenshot of a UWP app where a ListBoxItem is selected and pasting the image into MSPaint and checking the color: #FF91C1E7
3661-defaultlistbox.png

Using a screenshot of a UWP app where a Border Background is set to the default theme dictionary of ListBoxItemSelectedBackgroundThemeBrush: #FF4617B4
3662-listboxitemselectedbackgroundthemebrush.png

Using a screenshot of a UWP app where a Border Background is set to the non-theme ListBoxItem Selected Fill of SystemControlHighlightListAccentLowBrush: #FF99C9EF
3643-systemcontrolhighlightlistaccentlowbrush.png
This is visually close, but not what is being used.

0 Votes 0 ·
Show more comments

Hi, If you have any other questions, please feel free to contact us

0 Votes 0 ·