For the initial version, everything is good:
<ContentPresenter>
<ContentPresenter.Content>
<MultiBinding Converter="{StaticResource WhateverConverter}">
<Binding/>
<Binding Path="DummyObject"/>
</MultiBinding>
</ContentPresenter.Content>
</ContentPresenter>
But after I binded the Content
of ContentPresenter
to Tag
of the element, it don't work, and I wonder why this happens.
<ContentPresenter Content="{Binding Path=Tag, RelativeSource={RelativeSource Self}}">
<ContentPresenter.Tag>
<MultiBinding Converter="{StaticResource WhateverConverter}">
<Binding/>
<Binding Path="DummyObject"/>
</MultiBinding>
</ContentPresenter.Tag>
</ContentPresenter>
PS: I am using NotifyTask to implement an async value converter, so I need to perform a so-called two-step converting.
CodePudding user response:
You must know that the DataContext
of a ContentPresenter
is the Content
value. Therefore, the Binding
in the second example does not behave as you expect (different Binding.Source
).
In your second example, you set the ContentPresenter.Content
to bind to its own ContentPresenter.Tag
property. This makes ContentPresenter.Tag
the DataContext
of ContentPresenter
. Now the Binding
set on the Tag
property has the ContentPresenter.Tag
as Binding
source (DataContext
) and not the parent element's DataContext
.
If you want to do what you are doing, you should replace the ContentPresenter
with a ContentControl
. ContentControl
will not change its DataContext
.
The ContentPresenter
is primarily designed to be used inside the ControlTemplate
of a ContentControl
, where the ContentPresenter
automatucally binds to the parent ContentControl.Content
property. The persenter is only interested in the Content (to present it) and not the DataContext
of the parent control. That's why the ContentPresenter
has this special behavior regarding its DataContext
. Maybe the name ContentPresenter
makes a little more sense now.