Home > Software design >  Why WPF binding not work when bound to a tag of element itself
Why WPF binding not work when bound to a tag of element itself

Time:12-06

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.

  • Related