2009-05-15 1 views
5

MVVMパターンを初めて使用しようとしています。だからItemsControl私のviewmodelオブジェクトでいっぱい、DataTemplateのを使用して表示されます。オブジェクトはDataTemplateで表されたノードとエッジであり、ThumbPolylineオブジェクトであり、ノードとエッジを移動するためにItemsControlのクリックとドラッグを検出できるようにしたいと考えています。WPF:マウスイベントをビューモデルに添付するにはどうすればいいですか?

つの質問:

  • 私は少しのviewmodelsで処理するPolylineさんとThumb年代にマウスイベントハンドラをアタッチするにはどうすればよいですか? (私はThumbItemsControle.OriginalSourceポイントにThumb.DragDeltaハンドラをアタッチできますが、どのように私は、対応のviewmodelオブジェクトを取得するのですか?)
  • がどのように私は、マウスのクリックを検出するために、ItemsControlにマウスイベントハンドラを添付して、空白スペースにドラッグします? (答えは下にあります)

注:Viewのイベントを直接処理する場合、適切なViewModelとはみなされない可能性があります。しかし、重要な点は、私はマウスのイベントを処理する必要があると私はそれらを添付する方法がわからないことです。

答えて

2

私は2番目の質問に対する答えを見つけました。スクロールをサポートするItemsControlが必要でした。デフォルトのStackPanelではなく、グリッド上にアイテムを配置する必要がありました。両方の要件を満たすために、私はControlTemplateの使用:意味のあるマウスの座標(すなわち座標スクロール可能な空間)でマウスイベントを取得するために

<!--In the resources...--> 
<ControlTemplate x:Key="GraphTemplate" TargetType="ItemsControl"> 
    <ScrollViewer Name="ScrollViewer" 
        Padding="{TemplateBinding Padding}" 
        HorizontalScrollBarVisibility="Auto"> 
     ... 
      <Grid Name="Panel" IsItemsHost="True" 
        Background="{TemplateBinding ItemsControl.Background}"/> 
     ... 
    </ScrollViewer> 
</ControlTemplate> 
<!--Later...--> 
<ItemsControl x:Name="_itemsControl" 
       ItemsSource="{Binding Items}" 
       Template="{StaticResource GraphTemplate}" 
       Background="LightYellow"/> 

を、奇妙な呪文を使用してグリッドへの参照を取得する必要がありました:

Grid grid = (Grid)_itemsControl.Template.FindName("Panel", _itemsControl); 

イベントハンドラをグリッドにアタッチし、マウスイベントハンドラ内でマウス座標wrtを取得します全面にマウスイベントを取得するために

Point p = e.GetPosition((IInputElement)sender); 

を使用してグリッドは、コントロール(実際グリッド)は、バックグラウンドを有していなければならないので、私は、を介してグリッドに伝搬する、上記の背景=「淡黄色」に設定しますControlTemplateでのバインディング

6

DataTemplateのオブジェクトによって発生したイベントを処理する方法が見つかりました。

(1)(2)、イベントが適用されたアイテムを見つけるのFrameworkElementとしてOriginalSourceを扱い、そのDataContextのを取得するためのItemsControl

<ItemsControl x:Name="_itemsControl" 
       Thumb.DragStarted="Node_DragStarted" 
       Thumb.DragDelta="Node_DragDelta" 
       Thumb.DragCompleted="Node_DragCompleted" 
       MouseDoubleClick="OnMouseDoubleClick" 
       .../> 

にイベントハンドラをアタッチ:

void Node_DragStarted(object sender, DragStartedEventArgs e) 
{ 
    var os = (FrameworkElement)e.OriginalSource; 
    var vm = os.DataContext as ItemViewModel; 
    if (vm != null) 
     // do something with the item ViewModel 
} 
+2

+1 – Ant

1

コードビハインドなしでこれを行う方法があります...

あなたはまた、私はViewModelににInputBindingsをバインドするために書いたmarkup extensionを使用することができマーロングレックの実装here

を参照して、コマンドにイベントをマップするために添付の行動パターンを使用することができますが、このように、コマンド:

<UserControl.InputBindings> 
    <MouseBinding Gesture="LeftClick" Command="{input:CommandBinding SomeCommand}"/> 
</UserControl.InputBindings> 

しかし、私はそれがあなたの特定のニーズに合っているとは確信していません...

+0

これはグラフィカルオブジェクトを作成して移動するためのグラフィカルなインターフェイスなので、マウス座標が必要なので、ドラッグが進行中のときにフィードバックを表示する必要があります。 – Qwertie

3

ViewModelはGUIから切り離されていますので、コントロールやマウスクリックについては何も分かりません。

つのオプション:

  • コールのViewModel内のコマンド、トーマス
  • バインドビューモデル内のプロパティに親指の位置によって示唆されているように、その後、WPFの周りに制御が移るが更新されたときViewModelの位置の値。
+0

私は、親指をどのように動かすのですか? – Qwertie

+0

可動式サムコントロールを作成する方法の例については、http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part1.aspxを参照してください。 –

+0

このプロジェクトでは、DragDeltaイベントを処理することによって、コードビハインドで親指を移動するだけです。 – Qwertie

1

Bea Stollnitzには、「データバインドされたItemsControls間で項目をドラッグアンドドロップするにはどうすればよいですか」というタイトルのドラッグアンドドロップの例があります。私は、リンクを投稿するだろうが、StackOverflowは私をさせていません。

ドラッグが進行中で、最後にドロップされたときにアクションが実行されている間、UIフィードバックを分割したい場合があります。

しかし、私は上記のThomasとCameronに同意します。イベント処理とデータバインディングのミキシング/マッチングを制限する必要があります。イベント処理ルートを行っている場合は、一般的にデータバインディングの代替案を示すため、オブジェクトに「モデルの表示」という用語を使用しないでください。

+0

リンク:http://bea.stollnitz.com/blog/?p=53 – Qwertie

+0

これは私にとっては実際には役に立ちませんが、興味深い記事に感謝します! – Qwertie

0

私ははるかに洗練された方法を使用しています。私はPrism 2とデータ型を使用します。だから私がやったことはこれです:

<ItemsControl x:Name="SearchImagesList" ItemTemplate="{StaticResource SearchResultsAlbum}" 

と私はちょうどボタンを作成しました!

<DataTemplate x:Key="SearchResultsAlbum">       
    <Button CommandParameter="{Binding}"     
      Command="{Binding Source={x:Static PhotoBookPRMainModule:ServiceProvider.DesignEditorViewManager}, Path=NavigationCommands.NavigateSearchResultAction}"> 
関連する問題