4

現在、WPFとMVVMを使用しようとしていますが、最近、解決方法がわからない問題が発生しました。私はこれに慣れていないので、何かが本来あるべきものではない場合は、教えてください。

ParentViewModelを持つParentViewがあります。ParentViewは、独自のViewModelを持つ2つのビューSubViewAとSubViewBを保持します。これは私のParentView.xamlです:

<local:ViewBase.DataContext>
    <local:ParentViewModel x:Name="Model" />
</local:ViewBase.DataContext>

<Grid>
    <local:SubViewA Visibility="{Binding ElementName=Model, Path=SubViewAVisibility}" />
    <local:SubViewB Visibility="{Binding ElementName=Model, Path=SubViewBVisibility}" />
</Grid>

私がやりたいこと:SubViewModelBには、SubViewBにバインドされているプロパティがあります。ParentViewModelで特定のイベントが発生したときに、そのプロパティを変更したいと思います。これは、SubViewModelBのプロパティをParentViewModelのプロパティにバインドすることで実行する必要があると思いますが、どうすればよいかわかりません。ParentView.xamlで次のようなものを試しました。

<local:SubViewB Visibility="{Binding ElementName=Model, Path=SubViewBVisibility}" SomeProperty="{Binding ElementName=Model, Path=WhatIWantThePropertyToBe}" />

しかし、それは私をどこにも連れて行かなかった。では、どうすればこれを解決できますか?MVVMライトツールキットのメッセージングを介してそれを行うことができることは知っていますが、それは私がやろうとしていることにはちょっと不適切なようです。助言がありますか?

ありがとう

4

2 に答える 2

3

このEventAggregatorパターンの良い解決策のように聞こえます。Microsoft PrismTinyMessenger(非常に軽量)によって提供されるものなど、いくつかの優れた実装があります。

コード例として、次のようなことを行います(Prism、テストされていないコードを使用)

public class ParentViewModel
{
    private IEventAggregator eventAggregator;

    public ParentViewModel(IEventAggregator eventAggregator)
    {
       this.eventAggregator = eventAggregator;
    }

    public void PublishSomeEvent()
    {
        // When a condition occurs, publish an event any subscribers 
        // that may be listening
        this.eventAggregator.GetEvent<SomeEvent>()
            .Publish(new SomeEvent("Hello World!")));
    }
}

public class SubViewModel
{
    private IEventAggregator eventAggregator;

    public SubViewModel(IEventAggregator eventAggregator)
    {
       eventAggregator.GetEvent<SomeEvent>.SomeEvent(OnSomeEventOccurred);
    }

    public void OnSomeEventOccurred(SomeEvent arg)
    {
        // This method called when ParentViewModel publishes the event
        Console.WriteLine(arg.OptionalMessage);
    }
}

イベントの個別の宣言が必要になります。たとえば、私はこれを使用します

public SomeEvent : CompositePresentationEvent<SomeEvent>
{
    public SomeEvent(string optionalMessage)
    {
        this.optionalMessage = optionalMessage;
    }

    public string OptionalMessage { get { return optionalMessage; } } 
}
于 2012-05-28T12:57:16.703 に答える
1

SubViewModelあなたはあなたのParentViewModel権利のインスタンスを持っているだろうか?その場合は、イベントをキャッチしてParentViewModel、の特定のプロパティ値を手動で変更できますSubViewModel

これが完璧な方法かどうかはわかりませんが、これでうまくいくはずです。

別の方法は、SubViewのプロパティをParentViewModelのプロパティに直接バインドすることです。

このようなものを試してください

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type Window}}, Path=DataContext.ParentViewModelProperty}"
于 2012-05-28T12:16:43.967 に答える