微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UserControl的命名控件内部内容属性在运行时始终为null

如何解决UserControl的命名控件内部内容属性在运行时始终为null

|| 我创建了一个用户控件,可以将其重复用于其他目的。我定义了一个包含UIElement的Dependency属性,我将其表示为用户控件中区域之一的内容。 我注意到当我使用此控件时。并为content属性中的元素命名,它们在运行时始终显示为null。 MyContainer.xaml:
<UserControl x:Class=\"BSSApp.UI.Tests.MyContainer\" x:Name=\"userControl\"
    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"
    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"
    mc:Ignorable=\"d\"
    d:DesignHeight=\"300\" d:DesignWidth=\"400\">

    <Border x:Name=\"LayoutRoot\" Background=\"Green\" CornerRadius=\"20\" BorderBrush=\"#005500\" BorderThickness=\"10\">
        <ContentPresenter Content=\"{Binding ElementName=userControl,Path=MyContent}\" Margin=\"20\"/>

    </Border>
</UserControl>
MyContainer.xaml.cs
namespace BSSApp.UI.Tests
{
    public partial class MyContainer : UserControl
    {
        public static readonly DependencyProperty Mycontentproperty =
                    DependencyProperty.Register(\"MyContent\",typeof(UIElement),typeof(MyContainer),new PropertyMetadata(new Grid()));

        public UIElement MyContent
        {
            get
            {
                return (UIElement)GetValue(Mycontentproperty);
            }
            set
            {
                SetValue(Mycontentproperty,value);
            }
        }


        public MyContainer()
        {
            InitializeComponent();
        }
    }
}
和using类: UserControlContentBug.xaml:
<UserControl x:Class=\"BSSApp.UI.Tests.UserControlContentBug\"
    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"
    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"
    xmlns:t=\"clr-namespace:BSSApp.UI.Tests\"
    mc:Ignorable=\"d\"
    d:DesignHeight=\"300\" d:DesignWidth=\"400\">

    <Grid x:Name=\"LayoutRoot\" Background=\"White\">
        <t:MyContainer>
            <t:MyContainer.MyContent>
                <Button Name=\"btnWithName\" Click=\"btnWithName_Click\">Click Me</Button>
            </t:MyContainer.MyContent>
        </t:MyContainer>
    </Grid>
</UserControl>
以及后面的代码: UserControlContentBug.xaml.cs
 namespace BSSApp.UI.Tests
 {
     public partial class UserControlContentBug : UserControl
     {
         public UserControlContentBug()
         {
             InitializeComponent();
         }

         private void btnWithName_Click(object sender,RoutedEventArgs e)
         {
             // this throws an exception
             btnWithName.Tag=2;
         }
     }
  }
因此,有一个名为\“ btnWithName \”的按钮的声明。该变量确实在后面的代码中声明,但它持有null ...仅在将按钮声明在另一个用户控件的属性中时才会发生。 有人知道如何解决这个问题吗? 谢谢     

解决方法

我自己碰到了这个问题。生成的部分类(例如obj \\ UserControlContentBug.xaml.g.cs)定义了XAML中代码可访问的命名元素,使用FrameworkElement.FindName()进行这些分配。 根据MSDN:   诸如FindName之类的运行时API正在处理对象树。这些对象被加载到整个Silverlight插件的内容区域和CLR运行时引擎中。当从模板或运行时加载的XAML创建对象树的一部分时,XAML名称范围通常与该对象树的整体不相邻。结果是在对象树中可能存在一个给定的FindName调用找不到的命名对象。 由于MyContainer建立了自己的名称范围边界作为UserControl,因此从UserControlContentBug调用FindName()不会探索对象树的那一部分(其中 btnWithName已定义)。 解决这个问题的方法可能有几种,但是对我来说最简单的方法是: 给MyContainer命名(
x:Name=\"myContainer\"
)。 从Button(btnWithName)中删除名称,以便在生成的C#代码中不会保留相同名称的多余的,始终为空的变量。 在后面的代码中创建对Button的引用。 像这样:
namespace BSSApp.UI.Tests
{
    public partial class UserControlContentBug : UserControl
    {
        private Button btnWithName;

        public UserControlContentBug()
        {
            Loaded += UserControlContentBugLoaded;
            InitializeComponent();
        }

        private void UserControlContentBugLoaded(object sender,System.Windows.RoutedEventArgs e)
        {
            btnWithName = myContainer.MyContent as Button;
        }

        private void btnWithName_Click(object sender,RoutedEventArgs e)
        {
            // this throws an exception,not so much
            btnWithName.Tag=2;
        }
    }
}
希望这可以帮助。     ,尝试在按钮上使用x:Name而不是Name。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。