【问题标题】:NullReferenceException with referenced Control in ContentPresenter from custom UserControlNullReferenceException 与来自自定义 UserControl 的 ContentPresenter 中的引用控件
【发布时间】:2014-04-25 13:15:33
【问题描述】:

我创建了一个自定义 UserControl (SlideControl),其中包含一个 ContentPresenter(属性名称:PageContent)。在我的页面上,我使用 UserControl 并将一些 Xaml 添加到 PageContent。
其中一个控件有一个名称(testTb)。当我在编译时识别它背后的代码中的 testTb 时。在运行时我得到一个 NullReferenceException

我能做什么?

这就是我所拥有的:

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!!!
}

【问题讨论】:

    标签: c# xaml windows-phone-7 windows-phone-8 user-controls


    【解决方案1】:

    要达到 testTb,您必须这样做

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

    发生这种情况是因为 testTb 在不同的范围内

    编辑

    如果你的 XAML 完全是这样的:

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

    那么您应该可以使用 TextBox 执行此操作:

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

    编辑

    这是你需要的课程
    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;
        }
    }
    

    下面是你如何使用它:

    var testTb = SlideControl.PageContent.FindVisualChild<TextBlock>("testTb");
    
    if (testTb != null)
        testTb.Text = "test2";
    

    【讨论】:

    • 感谢您的回答。不幸的是,这对我不起作用...我尝试了 var testTb = (TextBox)SlideControl.PageContent.FindName("testTb"),因为我无法直接访问 PageContent。但是没有方法 FindName。我究竟做错了什么?谢谢!
    • 您没有 FindName,因为您的 PageContent 是 Object,您应该将其转换为 UiElement 或 FrameworkElement
    • 谢谢。它现在可以编译,但 testTb 仍然为空?顺便提一句。这意味着“testTb 在不同的范围内”是什么意思?
    • 就像它驻留在 ItemTemplate 中
    • 它不会因为我的原始代码失败的原因而失败吗? xaml 尚未实例化,代码访问它?
    猜你喜欢
    • 2023-03-29
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多