Data binding outside the visual tree. Data Context Context

I am trying to associate dynamic behavior with a visual element outside the logical and visual trees of WPF.

My problem is that the color of the RadChart chart is set in (quasi-path): RadChart.SeriesMapping.LineSeriesDefinition.Appearance.Stroke

I initially wanted to bind this property to the datacontext attribute of the chart in XAML. Naively, I just wrote the usual {Binding PlotBrush}

The compiler returned an error "Cannot find managed FrameWorkelement". After reading, I believe that this means that the datacontext solution in the hierarchy did not work. Because its ancestors (speaking XAML) have other types than FrameWorkElement and other relationships than the contents of the contents of the content control. At least that's my real understanding of this. Please correct me.

So I found the "DataContext Bridge" http://www.codeproject.com/KB/WPF/AttachingVirtualBranches.aspx

Simply put, you say that you bind the datacontext property of a structure element that is assigned at runtime to the datacontext (and not those that inherit it) before the datacontext of the FrameWorkElement instance in the resources . Then the same instance of the resource object is used to bind to the datacontext property of the "branch" that you want to "attach" to the inheritance dynamics of the DataContext. But the author of the article possessed the luxury of realizing the validation of the consumer of the observed property. SolidColorBrush is sealed, and I suppose it would be some kind of work to implement a full brush, even with a decorator.

In my case, this does not help me do what I want, but I am "so close." So I'm wondering if there is any aspect of XAML tricks that could help me.

<Window.Resources> <local:FrameWorkElement x:Key="DataContextBridge"/> </Window.Resources> 

However, it is unclear how I use it. There is no object for which a datacontext should be set. AppearanceSettings is not a FrameWorkElement element.

 <telerik:SeriesAppearanceSettings> <telerik:SeriesAppearanceSettings.Stroke> Ok, how do I use the fact that I can access the datacontext here? </telerik:SeriesAppearanceSettings.Stroke> </telerik:SeriesAppearanceSettings> 

So, the next step was appropriate, I could somehow get the brush object. I experimented with such things, just messing around:

.cs:

 public class ObservableBrush : FrameworkElement { public Brush Brush { get { return (Brush) GetValue(BrushProperty); } set { SetValue(BrushProperty, value); } } public static readonly DependencyProperty BrushProperty = DependencyProperty.Register("Brush", typeof (Brush), typeof (ObservableBrush), new UIPropertyMetadata(new SolidColorBrush(Colors.Black))); } 

XAML top:

 <Window.Resources> <local:ObservableBrush x:Key="StrokeBrush"/> </Window.Resources> 

Built-in XAML:

 <telerik:SeriesAppearanceSettings.Stroke> <Binding Path="Brush"> <Binding.Source> <Binding Source="{StaticResource ResourceKey=StrokeBrush}" Path="DataContext"/> </Binding.Source> </Binding> </telerik:SeriesAppearanceSettings.Stroke> 

“Binding” is not a structural element, nor is “source” a dependency property, so waiting time, of course, complains. I know that the Brush property will never return anything other than the default value specified in the registration of the dependency property.

It’s as if I’m going on the second day directly to this problem. I think my next two attempts will be as follows: * Make ObservableBrush a real brush. Then install it programmatically (use the standard dynamic resource binding instead). I do not like this. I wanted to do the data binding job. * Bridge BRUSH instead of DATACONTEXT.

The XAML part works great:

 <telerik:SeriesAppearanceSettings.Stroke> <Binding Source="{StaticResource ResourceKey=StrokeBrush}" Path="Brush"/> </telerik:SeriesAppearanceSettings.Stroke> 

But then again, how do I bind Brush to the DataContext property? Is there an override that I can use in an ObservableBrush to force Brush to dynamically follow the one in the datacontext?

How about creating a fake visual element in a tree and then link two bindings to it?

 <!-- Within the visual tree scope --> <SomeFrameWorkElementType> <SomeFrameWorkElemetType.SomeBrushProp> <Binding Source="{StaticResource ResourceKey=StrokeBrush}" Path="Brush" Mode="OneWayToSource"/> <Binding Stroke/> </SomeFrameWorkElemetType.SomeBrushProp> <SomeFrameWorkElementType> 

And does it somehow “connect” the two bindings?

Or is there some (un) official "helper class" for this type of function?

Or am I barking the wrong tree and (much) better permit this in coding through dynamic resource binding?

Any thoughts or comments on how to do this? Besides my obvious self-destructiveness for insisting on data binding when dynamic resources should solve this.

+7
source share
1 answer

you found a good article there by Josh Smith, but it is a little outdated. The same guy wrote an even better article about a year later, which covers almost the same question, but has better answers: The artificial context of inheritance

There, it uses the DataContextSpy class, and while I still do not fully get what you are trying to do, I will try to show you how you use it:

 <Grid><!-- this is some container where its DataContext has the PlotBrush Property--> <Grid.Resources> <spy:DataContextSpy x:Key="Spy"/> </Grid.Resources> <telerik:thisIsYourControl> <telerik:SeriesAppearanceSettings.Stroke> <Binding Source="{StaticResource Spy}" Path="DataContext.PlotBrush"/> </telerik:SeriesAppearanceSettings.Stroke> </telerik:thisIsYourControl> <Grid> 

I hope this helps and works for you. I haven't used telerik controls before, so I can't code the complete example, still hope this covers it.

+12
source

All Articles