1
votes

So i'm having some binding issues ATM with my "GroupColour" property on my ObjA class. I also have a CurrentState variable, which, based on its value, returns a Brush (this is done in the converter below).

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

namespace UIChemicalMelt
{
    public class StateToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            switch (value)
            {
                case State.INACTIVE:
                    return Utilities.ResourceDictionary["HoverOverColourInactive"] as Brush;
                case State.ACTIVE:
                    return Utilities.ResourceDictionary["HoverOverColourActive"] as Brush;
                case State.ACTIVE_GROUP_SET:
                    return Utilities.ResourceDictionary["BackgroundBasedOnGroupColour"] as Brush;
                case State.HIGHLIGHTED:
                    return Utilities.ResourceDictionary["HighlightThemeColour"] as Brush;
                case State.PROCESSING:
                    return Utilities.ResourceDictionary["ProcessingWellColour"] as Brush;
                default:
                    return Brushes.Transparent.Color;
            }
        }

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

It is used in my ControlTemplate Triggers of my buttons that I create in my View XAML

                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="Background" Value="{Binding CurrentState, Converter={StaticResource StateToColorConverter}}"/>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="False">
                        <Setter Property="Background" Value="{Binding CurrentState, Converter={StaticResource StateToColorConverter}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>

It all seems to work fine, but I get a XAML error...

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=GroupColour; DataItem=null; target element is 'SolidColorBrush' (HashCode=46663997); target property is 'Color' (type 'Color')

I don't know why tbh..

2
You might instead look at using using MultiTriggers where you can declare in XAML the various combinations of the current state and the checked state of the control. - coding.monkey
you should return SolidColorBrush instead of Brush. - Gaurang Dave
Thanks guys :) I'll give it a try - uaswpf
Where is the CurrentState property defined and what's the DataContext of the Button? - mm8
Managed to fix it @mm8, I had to remove my converter and use my GroupColour property instead which is a SolidColorBrush.... bit annoying though since the converter returns a SolidColorBrush..... - uaswpf

2 Answers

1
votes

When you simply choose a color in xaml WPF will automatically run your color through an implicit converter to wrap it in a brush. Since you're supplying your own converter you will no longer be able to benefit from the implicit WPF one and thus you'll want to return the brush yourself.

Heres your sample with just 'new SolidColorBrush' added to the various lines to satisfy the Background binding.

public class StateToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        switch (value)
        {
            case State.INACTIVE:
                return new SolidColorBrush(Utilities.ResourceDictionary["HoverOverColourInactive"]);
            case State.ACTIVE:
                return new SolidColorBrush(Utilities.ResourceDictionary["HoverOverColourActive"]);
            case State.ACTIVE_GROUP_SET:
                return new SolidColorBrush(Utilities.ResourceDictionary["BackgroundBasedOnGroupColour"]);
            case State.HIGHLIGHTED:
                return new SolidColorBrush(Utilities.ResourceDictionary["HighlightThemeColour"]);
            case State.PROCESSING:
                return new SolidColorBrush(Utilities.ResourceDictionary["ProcessingWellColour"]);
            default:
                return Brushes.Transparent;
        }
    }

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

Sorry, my answer can not solove your problem System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=GroupColour; DataItem=null; target element is 'SolidColorBrush' (HashCode=46663997); target property is 'Color' (type 'Color') and I think your code will not send this message and I need more code.

But your converter return a Color in this code return Brushes.Transparent.Color. And it will set the color to background that the backgroud value type is brush.

It also will send the bind message when you open the debug output window.

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=CurrentState; DataItem=null; target element is 'Grid' (Name=''); target property is 'Background' (type 'Brush')

How to fix it? Try to replace return Brushes.Transparent.Color to Brushes.Transparent and you can see this code.

            switch (value)
            {
                case State.INACTIVE:
                    return Utilities.ResourceDictionary["HoverOverColourInactive"] as Brush;
                case State.ACTIVE:
                    return Utilities.ResourceDictionary["HoverOverColourActive"] as Brush;
                case State.ACTIVE_GROUP_SET:
                    return Utilities.ResourceDictionary["BackgroundBasedOnGroupColour"] as Brush;
                case State.HIGHLIGHTED:
                    return Utilities.ResourceDictionary["HighlightThemeColour"] as Brush;
                case State.PROCESSING:
                    return Utilities.ResourceDictionary["ProcessingWellColour"] as Brush;
                default:
-                    return Brushes.Transparent.Color;
+                    return Brushes.Transparent;
            }