如何解决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 举报,一经查实,本站将立刻删除。