2

Siverlight プロジェクトに Galasoft の Light MVVM を使用しています。

指示どおりにすべてをセットアップしました。ViewModelは にバインドされていViewますDataContext

inkCanvasで名前が付けられたキャンバスがありViewます。

ViewModelが更新されたプロジェクト データを取得したら、参照してインスタンスinkCanvasを作成する必要があります。CanvasRenderpublic CanvasRender(Canvas canvas, ProjectData pdata)

問題は MVVMViewModelにありViewます。inkCanvasView

PS (編集済み): 私が行った回避策は次のとおりです。プロジェクト データを に渡すときに、 fromのコード ビハインドViewModelも渡します。うーん、今私のコード ビハインドはクリーンではありません。inkCanvasView

4

3 に答える 3

1

上記のコメントによると、これを行う1つの方法は、そのクラス内Canvasへの参照を拡張して保持することです。CanvasRender

public class MyCanvas : Canvas
{
    private CanvasRender _canvasRender;
    private ProjectData _data;

    public ProjectData Data
    {
        get { return _data; }       
        set
        {
            _data = value;
            _canvasRender = new CanvasRender(this, _data);
        }
    }

    public MyCanvas() : base()
    {
    }
}

ProjectDataおそらく依存関係プロパティも作成して、バインドできるようにしたいと思うでしょう。

これにより、XAML で記述できるようになったため、MVVM パターンを維持できます。

<local:MyCanvas ProjectData="{Binding ViewModel.ProjectData}" />
于 2012-09-25T18:28:54.397 に答える
0

EventToCommand アプローチを使用する場合 (別の回答で試しました)、PassEventArgsToCommand プロパティを使用する代わりに、CommandParameter プロパティを使用して Canvas にバインドします。

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <cmd:EventToCommand Command="{Binding Path=CanvasLoadedCommand}"
                            CommandParameter="{Binding ElementName=inkCanvas}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

次に、ViewModel で次のようにします。

public class ViewModel
{
    private Canvas m_canvas;

    public RelayCommand<Canvas> CanvasLoadedCommand { get; private set; }

    public ViewModel() 
    { 
        CanvasLoadedCommand = new RelayCommand<Canvas>(canvas =>  
        { 
            m_canvas = canvas;
        }); 
    }
}

そのため、キャンバスがロードされるとすぐに、それへの参照をビュー モデルに保存する必要があります。

于 2012-09-26T05:58:44.183 に答える
0

MVVM パターンでは、ViewModel でコントロールを直接参照しません。MVVM では、すべてが「バインディング」です。inkCanvas は ViewModel のプロパティにバインドされます。

public class MyViewModel : INotifyPropertyChanged
{
    private readonly StrokeCollection _mystrokes;

    public MyViewModel ()
    {
        _mystrokes= new StrokeCollection();
        (_mystrokesas INotifyCollectionChanged).CollectionChanged += delegate
        {
            //the strokes have changed
        };
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public StrokeCollection MyStrokes
    {
        get
        {
            return _mystrokes;
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

XAML:

<InkCanvas Strokes="{Binding MyStrokes}"/>

編集 :

おそらく、あなたの場合の回避策は EventToCommand を使用することです:これにより、XAML で UI イベントを ICommand に直接バインドできます (Args を使用して、inkCancas に参照を渡します)。

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=LoadedCommand}"
                            PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>
于 2012-09-24T19:40:21.153 に答える