簡體   English   中英

依賴項屬性PropertyChangedCallback異常

[英]Dependency Property PropertyChangedCallback exception

我在自定義控件中具有以下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..
    }

運行正常,但是如果我更改自定義控件的“屬性”面板中的屬性,則在運行時會引發異常:對象引用未設置為對象的實例。

在此處輸入圖片說明

編輯1:

忘記在Ellipse el = nn.GetTemplateChild("PART_inner") as Ellipse;帖子中添加一行代碼Ellipse el = nn.GetTemplateChild("PART_inner") as Ellipse;

編輯2:

雖然可以創建BooleanToVisibilityConverter並在Generic.xaml中使用Binding,但是HasConnectionChangedCallBack方法現在為空/無用。

Visibility="{Binding HasConnection, Converter={StaticResource BooleanToVisibiltyConverter}, RelativeSource={RelativeSource TemplatedParent}}"

編輯3:

找到了可能的解決方法。 首先調用屬性回調方法,然后再調用OnApplyTemplate()方法,因此不會在xaml中引發任何異常或錯誤。

在OnApplyTemplate()中,我添加

 if (this.HasConnection)
            PART_inner.Visibility = System.Windows.Visibility.Visible;
        else
            PART_inner.Visibility = System.Windows.Visibility.Hidden;

做這個

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

發生異常的原因是,當通過XAML解析器設置屬性時,尚未實例化UserControl的內容。

XAML解析器通過XAML從上到下進行工作。 UserControl只是用於定義它的XAML的快捷方式,因此,當XAML解析器在外部控件上設置HasConnection=True時,其內容尚未實例化,因此PART_Inner不存在。

解決方案是在用戶控件中定義HasConnection與依賴它的對象之間的關系,並牢記實例化順序。 例如,如果PART_Inner是一個UserControl,則可以在其Loaded事件中搜索其類型為NetworkNode的父級,以便HasConnection可以評估HasConnection 這可能是需要對現有代碼進行最少更改的解決方案。 保留更改處理程序(包括安全代碼)的狀態,並向包含的控件添加邏輯,該控件從其祖先讀取起始值。

其他選擇是完全不使用DependencyPropertyChanged回調,而是使用類型為FindAncestorRelativeSourceBooleanToVisibilityConverter在Visibility屬性上創建綁定。 還有一個想法是使用Trigger

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM