Question

I created a custom UserControl (SlideControl), containing a ContentPresenter (Property name: PageContent). On my page I use the UserControl and add some Xaml to the PageContent.
One of the controls there has a name (testTb). When I access the testTb in the code behind it is recognized at compile time. At run time I get a NullReferenceException.

What can I do?

This is what I have:

SlideControl.xaml:

<Canvas>
    <!-- some style here I want to use on every app page (slide in menu) -->
    <ContentPresenter Name="PageContentPresenter" />
</Canvas>

SlideControl.xaml.cs:

public object PageContent
{
   get { return PageContentPresenter.Content; }
   set { PageContentPresenter.Content = value; }
}

MainPage.xaml:

<helpers:BasePage x:Name="SlideControl">
    <helpers:BasePage.PageContent>
        <TextBox x:Name="testTb" />
    </helpers:BasePage.PageContent>
</helpers:BasePage>

MainPage.xaml.cs:

public MainPage() {
    InitializeComponent();
    this.testTb.Text = "test text"; // NullReferenceException!!!
}
Was it helpful?

Solution

To reach testTb you must do

var testTb = (TextBox)PageContent.FindName("testTb");
//use testTb as you want.

this happens because testTb is in a different scope

EDIT:

If your XAML is exactly like this:

<helpers:BasePage.PageContent>
    <TextBox x:Name="testTb" />
</helpers:BasePage.PageContent>

then you should be able to use TextBox doing this:

var testTb = (TextBox)PageContent;
testTb.Text = "Whatever you want to do";

EDIT

This is a class you need
MyVisualTreeHelper.cs

public static class MyVisualTreeHelper
{
    public static T FindVisualChild<T>(this FrameworkElement obj, string childName) where T : FrameworkElement
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            FrameworkElement child = (FrameworkElement)VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is T && child.Name == childName)
                return (T)child;
            else
            {
                T childOfChild = FindVisualChild<T>(child, childName);
                if (childOfChild != null)
                    return childOfChild;
            }
        }
        return null;
    }
}

and Here's how you use it:

var testTb = SlideControl.PageContent.FindVisualChild<TextBlock>("testTb");

if (testTb != null)
    testTb.Text = "test2";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top