x:如果元素包含在UserControl的内容中,则名称不起作用Silverlight

问题描述

|| 情况: 我有一个这样的\“ wrapper panel \”ѭ0((为简洁起见,删除名称空间和视觉细节):
<UserControl ...>
<Grid x:Name=\"LayoutRoot\" Background=\"White\">
    <ContentPresenter x:Name=\"integratedPanelContent\" Margin=\"5\" /> 
</Grid>
</UserControl>
然后在后台代码中,我注册一个依赖项属性
public FrameworkElement PanelContent
{
    get { return (FrameworkElement)GetValue(Panelcontentproperty); }
    set { SetValue(Panelcontentproperty,value); }
}
public static readonly DependencyProperty Panelcontentproperty =
    DependencyProperty.Register(\"PanelContent\",typeof(FrameworkElement),typeof(MyWrapperPanel),new PropertyMetadata(null,OnPanelContentChanged));

private static void OnPanelContentChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
    ((MyWrapperPanel)d).OnSetContentChanged(e);
}

protected virtual void OnSetContentChanged(DependencyPropertyChangedEventArgs e)
{
    if (PanelContent != null)
        integratedPanelContent.Content = PanelContent;
}
现在,我可以将任何内容包装到控件中:
<my:MyWrapperPanel x:Name=\"myWrap\">
    <my:MyWrapperPanel.PanelContent>
        <TextBlock x:Name=\"tbxnothing\" Text=\"nothing\" />
    </my:MyWrapperPanel.PanelContent>
</my:MyWrapperPanel>
问题描述: 每当我尝试在代码隐藏中使用引用tbxnothing时,系统都会抛出“ 4”,因为tbxnothing尽管作为引用存在,但并不指向XAML中定义的TextBlock,而是“ 5”。 可能的(但不方便的)解决方法: 有一种解决方法,我从TextBlock中删除了ѭ6,然后显式定义了名为
tbxnothing
的私有TextBlock。然后在
OnNavigatedTo
事件处理程序中,通过以下方式分配值:
tbxnothing = myWrap.PanelContent as TextBlock;
这是可行的,但不是正确的方法,因为如果内容是包含所需控件的堆栈面板,则我必须遍历树以查找所需内容,这非常不方便。 题: 为什么将文本块包装在User控件中(说明的方式)后不再可见,以及如何通过隐藏代码中的x:Name来获取它?     

解决方法

        问题在于您的面板内容介于两个凳子之间。一方面,在主页面的名称范围中创建名称为“ tbxNothing”的内容。但是,此时尚未将其添加到对象树中。另一方面,作为用户控件的MyWrapperPanel具有自己的名称范围,并在其下方的对象树中添加了名称为“ tbxNothing”的项目。主页上的
FindName
在MyWrapperPanel中找不到任何内容,因为它具有自己的名称范围,而在MyWrapperPanel上的
FindName
将找不到\“ tbxNothing \”,因为它在其名称范围中不存在(实际上是在主页)。 答案是不要将ѭ0用作ѭ13的基础。而是创建一个Silverlight模板控件。将其继承的基类修改为
ContentControl
,并调整其默认模板以包含
ContentPresenter
。应该看起来像这样:
public class MyWrapperPanel : ContentControl
{
    public MyWrapperPanel ()
    {
        this.DefaultStyleKey = typeof(MyWrapperPanel );
    }
}
然后在主题/generic.xaml中,样式可以如下所示:
<Style TargetType=\"local:MyWrapperPanel\">
    <Setter Property=\"Template\">
        <Setter.Value>
            <ControlTemplate TargetType=\"local:MyWrapperPanel\">
                <Grid>
                    <ContentPresenter />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
您的主页xaml看起来像:-
<my:MyWrapperPanel x:Name=\"myWrap\">
    <TextBlock x:Name=\"tbxNothing\" Text=\"Nothing\" />
</my:MyWrapperPanel>
请注意,从ѭ14衍生而来的是
Content
属性,the15ѭ将自动神奇地连接到该属性。