简体   繁体   中英

why content template of button does not have object?

i am just exploring windows phone runtime apps template . But i am seeing a weird thing.

I have Button defined in Xaml with ContentTemplate set in it. I wanted extract the Image control defined in the ContentTemplate of this button. But it is coming null.

Xaml code :-

<Button x:Name="PlayButton" Click="PlayButton_OnClick">
        <Button.ContentTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Name="Panel">
                    <Image x:Name="ControlImg" 
                     Width="100"
                    />
                    <TextBlock Text="text block" />
                </StackPanel>
            </DataTemplate>
        </Button.ContentTemplate>

Here is button Click event :-

private async void PlayButton_OnClick(object sender, RoutedEventArgs e)
{
        var btn = sender as Button;

        var ct = btn.ContentTemplate; // this part is also not showing controls in it when expending ct at runtime.

        var img = btn.FindName("ControlImg") as Image; // coming null 

        var stckpnl = btn.FindName("Panel") as StackPanel;// coming null
}

Can anybody check this out why is this happening ?

Edit :- I have broken my problem and reach this very bottom simple level and after seeing this i am just not getting why is this happening ?

That is strange behavior. It should have stack Panel and image in control template. As a work around you can use ContentTemplateRoot to get the image and stackpanel. I have test this, it is working.

((StackPanel)btn.ContentTemplateRoot).Children[0] // image

Hope this helps

Edit:

For Details about why FindName is not working see the the Remarks section on on MSDN . Here is some relevant quotes

Important In order to use the FindName method effectively, you should understand the concept of a XAML namescope, and how a XAML namescope is created at XAML load time and then referenced and possibly modified at run time. For more info see XAML namescopes. The most common usage of FindName in your Windows Runtime code will be from within the generated InitializeComponent call for a XAML page. In this situation, FindName is invoked only after the XAML page is loaded. InitializeComponent provides the infrastructure such that any object that was instantiated by XAML loading can conveniently be accessed by your code-behind code. You can then reference the objects as a variable that shares the same name as the markup-declared x:Name. A run-time API such as FindName is working against a run-time object tree of the app as it exists in memory. When part of this object tree is created from templates or run-time loaded XAML, a XAML namescope is typically not contiguous within that object tree. The result is that there might be a named object in the object tree that a given FindName scope cannot find. The discontinuities between XAML namescopes that you might encounter in typical application scenarios are when objects are created by applying a template, or when objects are created by a call to XamlReader.Load and subsequently added to the object tree.

As you are using DataTemplate so the xaml object tree is not contiguous so that is why FindName is failed to find the control from the xaml tree.

hope this explains...

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