Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF binding with PlacementTarget and RelativeSource

Can you explain the following WPF code:

DataContext="{Binding Path=PlacementTarget,RelativeSource={x:Static RelativeSource.Self}}">

I find it extremely confusing. What is placement target and what is relative source?

like image 752
MadSeb Avatar asked Feb 16 '11 19:02

MadSeb


People also ask

What are the use cases of relativesource in WPF?

In this article, I will expose the use cases of the RelativeSources in WPF. The RelativeSource is a markup extension that is used in particular binding cases when we try to bind a property of a given object to another property of the object itself, when we try to bind a property of a object to another one of its relative parents, when binding a ...

When should I use the relativesource property in CSS?

This is useful when you want to specify the source relative to where your binding target is. Some common scenarios where you may use this property is when you want to bind one property of your element to another property of the same element or if you are defining a binding in a style or a template. For more information, see RelativeSource.

How to bind a relative source with mode=findancestor?

When you use a relative source with Mode=FindAncestor, the binding must be like: Command=" {Binding Path=DataContext.CommandProperty, RelativeSource= {...}}" If you don't add DataContext in your path, at execution time it can't retrieve the property. If an element is not part of the visual tree, then RelativeSource will never work.

How to bind to a property in the DataContext of the relativesource?

Just wanted to note here that if you want to bind to a property in the DataContext of the RelativeSource then you must explicitly specify it: {Binding Path=DataContext.SomeProperty, RelativeSource=.... This was somewhat unexpected for me as a newbie when I was trying to bind to a parent's DataContext within a DataTemplate.


2 Answers

Every FrameworkElement has a DataContext that is an arbitrary object. The default source for a data binding is that DataContext. You can use RelativeSource.Self to change the source for a binding to the FrameworkElement itself instead of its DataContext. So the RelativeSource part just moves you "up one level" from the DataContext of the FrameworkElement to the FrameworkElement itself. Once you are at the FrameworkElement you can specify a path to any of its properties. If the FrameworkElement is a Popup, it will have a PlacementTarget property that is the other FrameworkElement that the Popup is positioned relative to.

In short, if you have a Popup placed relative to a TextBox for example, that expression sets the DataContext of the Popup to the TextBox and as a result {Binding Text} somewhere in the body of the Popup would bind to the text of the TextBox.

like image 136
Rick Sladkey Avatar answered Nov 15 '22 14:11

Rick Sladkey


This looks like a hack that is used for popup-elements such as ContextMenus and Popup-windows.
The problem with these elements is, that they are disconnected from the visual tree of your window. Therefore the DataContext is not available. The PlacementTarget is a link to an element of the visual-tree.
Mostly you will find a binding binding path like PlacementTarget.Tag where in the source element the Tag property has been set to the DataContext but in some situations, the element itself is also meaningfull, such as in your example.

Assuming that the above code is used in a ToolTip or a ContextMenu, the DataContext will be set to the control that "owns" the element.

Look at the post from (Gishu +1) for an explanation of the mechanics.

like image 34
HCL Avatar answered Nov 15 '22 13:11

HCL