0

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:

投稿にコードを 1 行追加するのを忘れていました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;
4

2 に答える 2

0

例外の理由は、プロパティが XAML パーサーを介して設定されたときに、UserControl のコンテンツがインスタンス化されていないためです。

XAML パーサーは、XAML を介して上から下へと機能します。UserControl は、それを定義する XAML の単なるショートカットであるため、XAML パーサーHasConnection=Trueが外側のコントロールを設定する時点では、そのコンテンツはまだインスタンス化されていないため、PART_Inner はまだ存在しません。

解決策は、HasConnection とそれに依存するものとの間の関係を、インスタンス化の順序を念頭に置いて UserControl 内で定義することです。たとえば、PART_Inner が UserControl の場合、その Loaded イベントで NetworkNode 型の親を検索して、HasConnection評価できるようにすることができます。これはおそらく、既存のコードへの変更を最小限に抑えるソリューションです。安全コードを含め、変更ハンドラーをそのままにして、含まれているコントロールにロジックを追加して、その祖先から開始値を読み取ります。

他のオプションは、DependencyPropertyChangedコールバックをまったく使用しないことですが、RelativeSource型指定されFindAncestorBooleanToVisibilityConverter. さらに別のアイデアは、を使用することTriggerです。

于 2013-05-30T09:57:21.603 に答える
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..
}
于 2013-05-30T01:50:42.920 に答える