0

非常に単純化されていますが、これが私の問題です:(下部の解決策)

AnimatableとINotifyPropertyChangeを継承するカスタムクラスがあり、1つのDependencyProperty(たとえば、1から10までアニメーション化)と1つの追加プロパティ(バインディングを使用してXAMLから使用したい)が含まれています。

MyClass : Animatable, INotifyPropertyChanged {

    public static DependencyProperty AnimateValueProperty = DependencyProperty.Register(
      "AnimateValue",
      typeof(double),
      typeof(MyClass)
     );

    public double AnimateValue {
        get { return (double)GetValue(AnimateValueProperty); }
        set {
                SetValue(AnimateValueProperty, value);
                OnPropertyChanged(new PropertyChangedEventArgs("AnimateValue"));
                OnPropertyChanged(new PropertyChangedEventArgs("GuiValue")); //Added in edit
            }
        }
    }

    public double GuiValue {
        get { 
            return AnimateValue + 10; 
            //More fancy stuff happening in the real class...
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
        if (PropertyChanged != null) {
            PropertyChanged(this, e);
        }
    }

    protected override Freezable CreateInstanceCore() {
        return new MyClass();
    }
}

GUI要素をプロパティにバインドすると(AnimateValue)、すべてが期待どおりに機能します。GUI要素を関連するプロパティ(GuiValue)にバインドすると、何も起こりません。変更されたイベントはそのプロパティに到達しないと思いますが、問題を解決する方法が本当にわかりません。ポインタはありますか?

どんな助けでも大歓迎です!

編集:AdamSillsとKaiWangからの2つの返信に感謝します。2回目のOnPropertyChange呼び出しを省略してくれたのは愚かでしたが、以前に試したのですが、うまくいきませんでした。デバッグするために、私はAnimateValue.set関数に書き込み行を入れて、見よ、それはまったく実行されません!

また、ゲッターを変更して、常に20を返すようにしました。変更はありません。:-oアニメーションはプロパティgetとsetを完全にスキップし、アニメーション化して基になる依存関係プロパティを読み取るようです...または私は誤解しましたか?私が使用するアニメーションコードは次のとおりです。

DoubleAnimation da = new DoubleAnimation (1, 10, new Duration(TimeSpan.FromSeconds(3)));
myClassInstance.BeginAnimation(MyClass.AnimateValueProperty, da);

うーん...ここにそのコードを書いた後、セッターが使用されていないことは非常に合理的です(私は本当にそれを望んでいますが!)-それでも、基本的な問題は残っており、ゲッターが使用されない理由がわかりません!

Edit2:解決策!

以下に示すように、DependencyPropertyに接続するプロパティにINotifyPropertyChangeを使用できませんでした。アニメーションとXAMLは内部でDepencencyPropertyを使用し、ゲッターとセッターをまったく使用しません。

したがって、-PropertyChangedCallbackは変更を他の人に通知し、CoerceValueCallbackはデータを「修正」します。データを検証することも可能です。これはすべて、DependencyPropertyコンストラクターで行われます。皆さんありがとう!

ありがとう!

/ビクター

4

4 に答える 4

2

AnimateValueの値を設定することにより、変更されたことをWPFに通知します。ただし、GuiValueが変更されたことをWPFに通知することはありません。WPFデータバインディングフレームワークは、GuiValueが変更されたことを、通知しない場合にどのように認識しますか?

AnimateValueを更新して変更の通知を発行する場合(これ自体は依存関係プロパティであるため必要ありません)、GuiValueはAnimateValueに依存しますが、プロパティ内で手動で計算されるため、GuiValueに関する通知も発行する必要があります。

基本的に追加するだけです

OnPropertyChanged(new PropertyChangedEventArgs("GuiValue"));

AnimateValueセットブロックに。

アップデート:

新しい編集に基づいて、XAMLを介してプロパティ設定を行う場合、依存関係プロパティのゲッター/セッターが呼び出されることはなく、すべてGetValue/SetValueを介して直接行われます。

変更にローカルで応答する必要がある場合は、OnPropertyChangedをオーバーライドするか、DependencyProperty.Register内に変更コールバックを提供します

于 2009-09-21T00:12:10.130 に答える
2

これは、依存関係プロパティで使用するためのプロパティ変更通知パターンです。

  public Boolean PasswordBoxVisible {
     get { return (Boolean)GetValue(PasswordBoxVisibleProperty); }
     set { SetValue(PasswordBoxVisibleProperty, value); }
  }

  public static readonly DependencyProperty PasswordBoxVisibleProperty =
      DependencyProperty.Register("PasswordBoxVisible", typeof(Boolean), typeof(UserControl), new UIPropertyMetadata(false, new PropertyChangedCallback(PropChanged)));

  //this method is called when the dp is changed
  static void PropChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) {
       UserControl userControl = o as UserControl;
       //now you can use this to call some methods, raise other value changed etc, in this case OtherProperty.
       userControl.NotifyPropertyChanged("OtherProperty");
  }

私はあなたがしなければならないかもしれないことは他の価値観を強要することであると感じていますが、完全には確信していません。この記事の強制値コールバックのセクションをご覧ください

于 2009-09-21T05:49:09.033 に答える
1

私はあなたが何を意味するのか理解できるかどうかわかりません。しかし、これが役立つかどうかを確認してください。

    public double AnimateValue {
    get { return (double)GetValue(AnimateValueProperty); }
    set {
            SetValue(AnimateValueProperty, value);
            OnPropertyChanged(new PropertyChangedEventArgs("AnimateValue"));
            OnPropertyChanged(new PropertyChangedEventArgs("GuiValue "));
        }
    }
}
于 2009-09-21T00:11:43.937 に答える
1

オブジェクトがDependencyObjectから派生している場合、Bindingアーキテクチャはバインディングを使用するためにDependency Property Resgistrationのみを使用するため、INotifyPropertyChangedを使用することはできません。

このためには、以下で説明する読み取り専用の依存関係プロパティが必要です。

public static DependencyProperty AnimateValueProperty = 
   DependencyProperty.Register(
      "AnimateValue",
      typeof(double),
      typeof(MyClass)
   );

 // This is for the Readonly GuiValueKey property
 public static DependencyPropertyKey GuiValueKey = 
     DependencyProperty.RegisterReadOnly (
     "GuiValue",
      typeof(double),
      typeof(MyClass),
      new UIPropertyMetadata(0.0)
);

public double AnimateValue {
    get { return (double)GetValue(AnimateValueProperty); }
    set {
            SetValue(AnimateValueProperty, value);
            // Following statement update GuiValue wherever it
            // is binded
            this.SetValue(GuiValueKey,value + 10);
        }
    }
}

// you dont even need following line...
// but its good to have it..
public double GuiValue {
    get { 
        return (double)this.GetValue(GuiValueKey); 
    }
}
于 2009-09-21T06:36:35.080 に答える