OmegaLol21
OmegaLol21

Reputation: 87

How to access nested property in WPF?

I don't know if nested property is the right word but I'm trying to access a property SystemParameters.WindowGlassColor.R in WPF. I am using AdonisUI for my UI in my WPF application. I am trying to edit the accent color to the Windows 10 accent color.

I already tried doing this:

<Color x:Key="{x:Static adonisUi:Colors.AccentColor}" 
       R="{Binding Source={x:Static SystemParameters.WindowGlassColor.R}}" />

but I get a error about WPF not supporting nested classes:

Error: Nested types are not supported: SystemParameters.WindowGlassColor.

Trying to look it up brings me to threads about changing the color of a TextBox and stuff instead of this <Color> thing. If anyone who has used AdonisUI can help me out or someone who knows how to do this can help, I would be grateful.

Upvotes: 2

Views: 441

Answers (2)

Khiro
Khiro

Reputation: 106

Simpler answer is: use Path to access nested properties.

The following code will work without issues:

<Color x:Key="{x:Static adonisUi:Colors.AccentColor}" 
       R="{Binding Source={x:Static SystemParameters.WindowGlassColor}, Path=R}" />

Edit: I rushed to post the answer before testing, and the above code will give the following error:

Error XDG0062 Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.Byte'.

However, the solution of using Path is still valid for bindable properties.

Upvotes: 1

Tam Bui
Tam Bui

Reputation: 3038

As @Stefan stated in the comments, you can't bind to R because it is not a DependencyProperty. However, you can create a ValueConverter to grab the red channel of WindowGlassColor, and override the R value on AdonisUI's AccentBrush.

Like this:

App.xaml:

<Application x:Class="AdonisUiTest.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:AdonisUiTest"
             xmlns:adonisUi="clr-namespace:AdonisUI;assembly=AdonisUI"
             StartupUri="MainWindow.xaml">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/AdonisUI;component/ColorSchemes/Dark.xaml"/>
                    <ResourceDictionary Source="pack://application:,,,/AdonisUI.ClassicTheme;component/Resources.xaml"/>
                </ResourceDictionary.MergedDictionaries>

            <!-- Override colors as you like -->
            <local:RedChannelConverter x:Key="RedChannelConverter"/>
            <SolidColorBrush x:Key="{x:Static adonisUi:Brushes.AccentBrush}" Color="{Binding Source={x:Static SystemParameters.WindowGlassColor},Converter={StaticResource RedChannelConverter}}"/>
        </ResourceDictionary>
        </Application.Resources>
</Application>

RedChannelConverter:

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;

namespace AdonisUiTest
{
    public class RedChannelConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                Color color = (Color)value;
                Color accent = (Color)App.Current.FindResource(AdonisUI.Colors.AccentColor);
                return new Color() { R = color.R, G = accent.G, B = accent.B, A = accent.A };
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{ex.GetType()}: {ex.Message}");
                return Colors.Transparent;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

MainWindow.xaml: Show a button that uses this accent

<Window x:Class="AdonisUiTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:adonisUi="clr-namespace:AdonisUI;assembly=AdonisUI"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Style>
        <Style TargetType="Window" BasedOn="{StaticResource {x:Type Window}}"/>
    </Window.Style>
    <Grid>
        <Border>
            <Button Style="{DynamicResource {x:Static adonisUi:Styles.AccentButton}}" Margin="5" Padding="5" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Click Me" FontSize="64"/>
        </Border>
    </Grid>
</Window>

Upvotes: 1

Related Questions