2010-05-26 24 views
1

在我看來,我有:如何在我的WPF 3D應用程序中MVVM-ize這個MouseDown代碼?

<UserControl x:Class ... MouseDown="UserControl_MouseDown"> 
    <Viewport3D Name="Viewport" Grid.Column="0"> 
     ... 
    </Viewport3D > 
</UserControl> 

在我的代碼隱藏,我有:

private void UserControl_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    ((MapPanelViewModel)DataContext).OnMouseDown(e, Viewport); 
} 

在我看來模型,我有:

public void OnMouseDown(MouseEventArgs e, Viewport3D viewport) 
{ 
    var range = new LineRange(); 
    var isValid = ViewportInfo.Point2DtoPoint3D(viewport, e.GetPosition(viewport), out range); 
    if (!isValid) 
     MouseCoordinates = "(no data)"; 
    else 
    { 
     var point3D = range.PointFromZ(0); 
     var point = ViewportInfo.Point3DtoPoint2D(viewport, point3D); 
     MouseCoordinates = e.GetPosition(viewport).ToString() + "\n" + point3D + "\n" + point; 
    } 
} 

我真的沒有很好的理解如何使用MVVM處理鼠標事件。我總是最終把它們放在代碼隱藏中,並將DataContext作爲SomeViewModel,然後將MouseEventArgs傳遞給我的視圖模型中的處理程序。這已經夠糟糕了,但在這種情況下,我實際上傳遞了一個控制(一個Viewport3D),這對於在2D和3D之間轉換座標是必需的。

有關如何使這更符合MVVM的任何建議?

回答

0

我結束了使用MVVM Messenger。所以,鼠標事件在後面的代碼中被處理,然後它發送一個事件發生的消息。然後,我的ViewModel可以訂閱此消息並接收通知。像魅力一樣工作,並保持一切解耦。

2

我認爲這是一個MVVM太過分了。當然,MVVM並沒有被精確地定義,但我認爲它是在嘗試將我的應用程序的高級機制和行爲與這些機制和行爲如何使用特定的UI技術實現的細節分離開來的(現在只是WPF當然,但我覺得假裝可能還有別的東西是有用的)。

不知道你的應用程序應該如何對鼠標事件作出反應,很難給出具體的建議或意見。基於我所做的做的可以看到,我認爲座標轉換最好留在UI層,然後翻譯後的座標通過方法調用傳遞給ViewModel。

+0

@DanM我們一直在採取這種方法,進入ViewModel的邏輯應該在UI主機之外工作。如果你要在特定的代碼上運行測試,它會執行還是失敗,因爲沒有ViewportInfo?如果失敗了,那麼這個邏輯應該像Daniel所說的那樣回到用戶界面。記住MVVM的主要優點之一就是自動單元測試。 – Agies 2010-05-27 03:07:16

1

如果您擔心通過將View對象傳遞給ViewModel來打破可測試性,請創建一個用於在3D和2D點之間轉換的接口,然後將其傳遞。在您的代碼背後,您將通過一個實現該接口的包裝器傳遞Viewport3D對象。

除此之外,我不會擔心代碼後面的事件處理程序。對所有容易使用的綁定使用綁定,爲真正棘手的部分使用代碼。

相關問題