1

WPFコントロールに奇妙な問題があります。基本的に、プライマリコンテンツの前にモーダルコンテンツを表示するコントロールがあります。私のコントロールは、ここに示されている私の答えの修正です。

モーダルコンテンツを非表示/表示するために使用されるというBool依存関係プロパティがあります。IsShownプロパティは次のように定義されます。

public static readonly DependencyProperty IsShownProperty =
    = DependencyProperty.Register("IsShown",
    typeof(bool), 
    typeof(ModalContentControl), 
    new UIPropertyMetadata(false, IsShownChangedCallback));

次のような標準の.Netプロパティラッパーがあります。

public bool IsShown
{
    get { return (bool)GetValue(IsShownProperty); }
    set { SetValue(IsShownProperty, value); }
}

プロパティが変更されたコールバックは次のようになります。

private static void IsShownChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ModalContentControl control = (ModalContentControl)d;

    if ((bool)e.NewValue == true)
    {
        control.ShowModalContent();
    }
    else
    {
        control.HideModalContent();
    }
}

およびメソッドにはShowModalContentHideModalContentモーダルコンテンツをそれぞれ表示および非表示にするロジックが含まれています。

ウィンドウにこのコントロールがあり、IsShownプロパティはviewModelにバインドされています。IsShownコントロールのプロパティにバインドされているブールプロパティを変更するコマンドを呼び出すボタンを押すことができます。モーダルコンテンツは、期待どおりに表示および非表示になります。

私の問題は、メソッドShowModalContentHideModalContentメソッドが公開されているため、コードから呼び出すことができるという事実にあります。ShowModalContentたとえば、私がやりたいのは呼び出しです。IsShownプロパティをクエリすると、正しい値(この場合はtrue)が報告されます。EG通常のプロパティを使用している場合は、次のようなタイプのバッキングフィールドがありますBool。メソッドで更新されます。このフィールドは、プロパティgetステートメントによって返されます。

しかし、私のプロパティは依存関係プロパティであるため、バッキングフィールドにアクセスできません。メソッドから値を更新する唯一の方法は、.netラッパーを介して依存関係プロパティを設定することですが、これによりコントロールが機能しなくなります(コンテンツが表示されると、再度削除することはできません)。

IsShownこの動作は、プロパティ変更コールバックを呼び出すメソッドでプロパティを設定することによって引き起こされる可能性があると思いました。呼び出し元のIsShownプロパティを設定します。しかし、WPFがこのシナリオから保護することをどこかで読んだことを覚えています。

では、ブール依存関係プロパティが正しい値を報告するように、この問題を修正するにはどうすればよいですか?

4

1 に答える 1

0

少し考えて(そして運が良ければ)、私は何とか問題が何であるかを理解することができました。これを機能させるために変更する必要があることが2つありました。

最初の問題は、ShowModalContentHideModalContentメソッドが2つのことを行っていることでした。

  1. プロパティを設定しIsShownます。
  2. コントロールの状態を更新しています。

プロパティを変更すると、とメソッドのいずれかが呼び出され、メソッドがIsShownプロパティを変更するため、これは問題でした。無限ループの発生は止まると思いますが、値をキャッシュしてコードでこれを管理しようとしても、大きな頭痛の種でした。IsChangedCallbackShowModalContentHideModalContentIsShownWPF

私のインスピレーションの瞬間は、パブリックメソッドが実行する必要があるのはプロパティを設定することだけであることに気付いたときです。私のパブリックメソッドは次のようになります。

public void ShowModalContent()
{
    IsShown = true;
}

public void HideModalContent()
{
    IsShown = false;
}

次に、これにより、コントロールの状態を更新するプロパティ変更コールバックがトリガーされます。

私の2番目のインスピレーションの瞬間は、ViewModelがIsShownプロパティの状態を正確に反映しておらず、これは明らかにデフォルトの依存関係プロパティのバインドモードがであるという事実が原因であることに気付いたときですOneWayDependencyProperty定義バインディングモードをに更新しただけBindsTwoWayByDefaultで、すべてが正常に機能するようになりました。

IsShownProperty = DependencyProperty.Register("IsShown",
    typeof(bool), typeof(ModalContentControl), 
    new FrameworkPropertyMetadata(false, 
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
        IsShownChangedCallback));
于 2012-06-29T15:33:16.247 に答える