简体   繁体   中英

How does NameScope in WPF work?

I'm having a strange behavior with NameScopes in WPF, I have created a CustomControl called FadingPopup which is a child class of Window with nothing special inside.

<Window.Resources>
    <local:FadingPopup>
        <Button Name="prec" Content="ahah"></Button>
        <Button Content="{Binding ElementName=prec, Path=Content}"></Button>
    </local:FadingPopup>
</Window.Resources>

In this snippet, the binding doesn't work (always empty). If I move these buttons from the resources to the content of the window like this :

<Window ...>
    <Button Name="prec" Content="ahah"></Button>
    <Button Content="{Binding ElementName=prec, Path=Content}"></Button>
</Window>

The binding works as expected.

Now, I have tried a mix between these two snippets :

<Window...>
    <Window.Resources>
        <local:FadingPopup>
            <Button Name="prec" Content="Haha"></Button>
        </local:FadingPopup>
    </Window.Resources>
    <Button Content="{Binding ElementName=prec, Path=Content}"></Button>
</Window>

It works as well.

Apparently, if the button prec is in the resources it registers itself in the NameScope of the Window. BUT, it seems that the Binding tries to resolve ElementName with the NameScope of the FadingPopup (which is null), thus the binding doesn't work...

My first snipped works well if I specify a NameScope in my class FadingPopup :

static FadingPopup()
{
    NameScope.NameScopeProperty.OverrideMetadata(typeof(FadingPopup), new PropertyMetadata(new NameScope()));
}

But I don't like this solution because I don't understand why, in the first snippet, prec is registered in the NameScope of Window, but ElementName is resolved with the NameScope of FadingGroup (which is null by default)...

Does someone can explain to me what is going on ? Why my first snippet doesn't work, if I don't specify a default NameScope for FadingGroup ?

How to: Define a Name Scope | Microsoft Docs provides a descent explanation on the matter.

You should check your DataContext on your control, do something like this and you should be OK. You might have to add a path, but probably not.

<Window.Resources>
    <local:FadingPopup DataContext="{Binding}">
        <Button Name="prec" Content="ahah"></Button>
        <Button Content="{Binding ElementName=prec, Path=Content}"></Button>
    </local:FadingPopup>
</Window.Resources>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM