我在自定义控件中有以下DependencyProperty
:
public bool HasConnection
{
get { return (bool)GetValue(HasConnectionProperty); }
set { SetValue(HasConnectionProperty, value); }
}
public static readonly DependencyProperty HasConnectionProperty =
DependencyProperty.Register(
"HasConnection",
typeof(bool),
typeof(NetworkNode),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(HasConnectionChangedCallBack)));
private static void HasConnectionChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NetworkNode nn = (NetworkNode)d;
Ellipse el = nn.GetTemplateChild("PART_inner") as Ellipse;
if (el.PART_inner.Visibility == ...) <-- exception el is null
//..code..
}
运行正常,但是如果我在自定义控件的“属性”面板中更改属性,则在运行时抛出异常:对象引用未设置为对象的实例。
EDIT1:
忘记在帖子Ellipse el = nn.GetTemplateChild("PART_inner") as Ellipse;
EDIT2:
创建BooleanToVisibilityConverter并在Generic.xaml中使用Binding有效,但HasConnectionChangedCallBack方法现在为空/无用。
Visibility="{Binding HasConnection, Converter={StaticResource BooleanToVisibiltyConverter}, RelativeSource={RelativeSource TemplatedParent}}"
EDIT3:
找到了一个可行的解决方案。首先调用属性回调方法,然后调用OnApplyTemplate()方法,因此不再抛出异常或xaml中出现错误。
在OnApplyTemplate()中我添加
if (this.HasConnection)
PART_inner.Visibility = System.Windows.Visibility.Visible;
else
PART_inner.Visibility = System.Windows.Visibility.Hidden;
答案 0 :(得分:0)
这样做
private static void HasConnectionChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null)
return;
NetworkNode nn = (NetworkNode)d;
if (nn == null || nn.Part_inner == null )
return;
if (nn.PART_inner.Visibility == ...) <-- exception
//..code..
}
答案 1 :(得分:0)
异常的原因是当通过XAML解析器设置属性时,UserControl的内容尚未实例化。
XAML解析器通过XAML从上到下运行。 UserControl只是定义它的XAML的快捷方式,因此,当XAML解析器在外部控件上设置HasConnection=True
时,其内容尚未实例化,因此PART_Inner尚不存在。 / p>
解决方案是以一种保持实例化序列的方式定义HasConnection与UserControl中依赖它的任何关系。例如,如果PART_Inner是UserControl,则可以在其Loaded事件中搜索其类型为NetworkNode的父级,以便可以评估HasConnection
。这可能是需要对现有代码进行最少更改的解决方案。保留更改处理程序,包括安全代码,并将逻辑添加到包含的控件中,该控件从其祖先读取起始值。
其他选项可能是根本不使用DependencyPropertyChanged
回调,而是使用RelativeSource
键入的FindAncestor
和BooleanToVisibilityConverter
在Visibility属性上创建Binding。另一个想法是使用Trigger
。