0

This seems like it should be simple as pie but I can't figure it out.

I am trying to change a working Style Setter for a "Fill" property on an element to actually declare a SolidColorBrush object in XAML in the Setter.Value. Unfortunately, in my brush declaration, I cannot seem to "get at" the DataContext of the very object whose Fill I am attempting to set. How may do I do this?

Below is the Style with setter. It uses a converter that takes an enum value ("Usage") and returns a Color value. The converter is fine but the binding fails because it cannot find the object.

<core:UsageToColorConverter x:Key="CvtUsageToColor"/>

<Style x:Key="RegionBandStyle" 
       TargetType="{x:Type tk:CartesianPlotBandAnnotation}">

    <!--  Help Intellisense show us the correct bindings when coding  -->

    <d:Style.DataContext>
        <x:Type Type="gci:IProfileRegion" />
    </d:Style.DataContext>


    <Setter Property="Fill">
        <Setter.Value>
            <SolidColorBrush >
                <SolidColorBrush.Color>
                    <!-- THIS BINDING FAILS:  It cannot find the "ancestor" CartesianPlotBandAnnotation
                         in order to get at its DataContext
                    -->
                    <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type tk:CartesianPlotBandAnnotation}}" 
                        Path="DataContext.(gci:IProfileRegion.Usage)"
                        Converter="{StaticResource CvtUsageToColor}"/>
                </SolidColorBrush.Color>
            </SolidColorBrush>
        </Setter.Value>
    </Setter>

</Style>

The binding fails with this message:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Telerik.Windows.Controls.ChartView.CartesianPlotBandAnnotation', AncestorLevel='1''. BindingExpression:Path=DataContext.Usage; DataItem=null; target element is 'SolidColorBrush' (HashCode=39731869); target property is 'Color' (type 'Color')

I suppose this makes sense. My dim understanding is that Brush is not in the visual (or logical) tree, right? So it can't find an ancestor? Is that the reason?

The original version of this Setter worked but it was much simpler. It just used a similar converter that returns a SolidColorBrush instead of a color:

    <Setter Property="Fill"  Value="{Binding Usage, Converter={StaticResource CvtUsageToBrush}}"/>

This worked fine but unfortunately (for unrelated reasons), I need to do things the other way; I need to declare the Brush explicitly myself using Property Element Syntax

Can someone tell me what binding voodoo I need here to get at the DataContext of the CartesianPlotBandAnnotation in my SolidColorBrush color binding?

(This is the sort of Binding issue that makes my head spin no matter how many times I read up on the Logical and Visual trees. My searches keep bringing up related topics but not the one I want. )

Joe
  • 5,394
  • 3
  • 23
  • 54
  • may I ask you to visit [my question](https://stackoverflow.com/questions/61445818)? Guessing that you know the answer. – aepot Apr 27 '20 at 20:12
  • I thinked twice and the only way see is `RelativeSource="{RelativeSource Self}"` – aepot Apr 27 '20 at 20:39
  • Unfortunately that doesn't seem to work. I tried it. I wouldn't expect it to since it merely refers me back to the same SolidColorBrush I am in the process of declaring. SolidColorBrush has no DataContext since it is not a FrameworkElement – Joe Apr 27 '20 at 21:02

1 Answers1

0

The FindAncesstor mode of the RelativeSource may be used to find a parent item in the Visual Tree. However, this is not the case. The brush color should inherit the element data context. Try to remove the RelativeSource setter at all. Also, are you sure that the Usage is the attached property? If not, simply set "Usage" in the Path. If this does not help, at least you will get a new error message saying which object is actually provide in the DataContext of CartesianPlotBandAnnotation.

Update: In case of interface binding, it should be enough to set Path to "(gci:IProfileRegion.Usage)". I have just tested this code and confirm that it works correctly: https://github.com/Drreamer/ColorInterfaceBinding If it does not work in your project, please clarify what exception is raised in this case. It helps to find the exact cause of the issue.

Drreamer
  • 332
  • 1
  • 10
  • Hi, thank you for the answer, I might not have been clear. The DataContext of the CartesianPlotBandAnnotation is correct. It is, in fact, an instance of my interface (IProfileRegion), as it should be I know this because other bindings in the style (which I admittedly don't show) do work against that data context. And my older "Fill" binding works against it too. The problem I'm seeing is that the SolidColorBrush I'm trying to declare appears somehow unable to access it. – Joe Apr 27 '20 at 23:00