依存関係プロパティを利用する WPF のビジュアル コントロールがあります。これらのプロパティは、クラスであるフィールドによってサポートされており、含まれているクラスが実際に変更されたときに、プロパティの値が変更されたことをすべてのバインディングに通知する必要がある場合があります。
簡単に言った:
- MyDepProp は MyClass 型です。
- MyClass の内容は、コントロールの内部操作によって変更されます。
- MyDepProp が変更され、MyClass の変更を反映できるように、皆さんにお知らせしたいと思います。
MSDN によると、依存関係プロパティが初めて使用されるときに、PropertyChanged が DependencyObject にアタッチされます。Visual Studio 2010 で動作します。ただし、Visual Studio 2012 をインストールした後、動作しなくなりました。DP が使用されていても (たとえば、バインディングがアタッチされていても)、PropertyChanged は null であり、変更を誰にも通知できません。
私はまだVisual Studio 2010コンパイラツールキットを使用しているので、VS 2012とともに更新された壊れたフレームワークの問題のようです.
PropertyChanged イベントを正しく使用していますか? それとも、VS 2012 によって更新された .NET 4.0 フレームワークのバグですか? 誰かが同様の問題に遭遇しましたか?
編集:バグのあるコードの一部:
public partial class MyImageControl : INotifyPropertyChanged,
IHandle<ImageRefresh>
{
// ***************************
// *** Dependency property ***
// ***************************
private void OnDataSourceChanged()
{
// ...
}
private static void DataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is MyImageControl)
((MyImageControl)d).OnDataSourceChanged();
}
public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource",
typeof(IDataSource),
typeof(MyImageControl),
new PropertyMetadata(null, DataSourceChanged));
public IDataSource DataSource
{
get
{
return (IDataSource)GetValue(DataSourceProperty);
}
set
{
SetCurrentValue(DataSourceProperty, value);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("DataSource"));
}
}
// ***********************************
// *** INotifyPropertyChanged impl ***
// ***********************************
public event PropertyChangedEventHandler PropertyChanged;
// *************************************
// *** Method, which exposes the bug ***
// *************************************
public void Handle(ImageRefresh message)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("BackgroundKind"));
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("DataSource"));
}
}
参考までに、IHandle インターフェイスは次のとおりです。
public interface IBaseHandle { }
public interface IHandle<TMessage> : IBaseHandle
{
void Handle(TMessage message);
}
シナリオ:
- DataSourceは、
Binding
- 誰かが
Handle
コントロールのメソッドを呼び出します (IHandle
インターフェースを使用) - PropertyChanged が null ではないかどうかのチェックを処理するため、DataSource の変更に関する情報は伝達されません。