[英]WPF - MVVM: how to draw a movable Rectangle with mouse
我是 WPF 的新手,我想使用 MVVM 模式創建一個程序(不使用 MvvmLight 等外部庫)。 該應用程序允許用戶使用鼠標在 canvas 內繪制矩形(以及將來的其他形狀)(類似於 Windows 繪圖,只是為了清楚起見)。 用戶也可以使用鼠標交互來移動/調整創建的矩形。
此時我實現了一個基本版本,用戶可以通過單擊按鈕添加一個矩形(具有隨機大小/位置)。 這是實現此行為的 MainWindow 視圖的代碼:
...
Title="{Binding Path=Titolo}"
Height="450" Width="800"
d:DataContext="{d:DesignInstance vm:MainWindowViewModel}">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="Add Rectangle" Command="{Binding AddShapeCommand}" />
</StackPanel>
<Canvas>
<ItemsControl ItemsSource="{Binding AllShapeCollection}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type vm:MyRectViewModel}">
<uc:MyRectView/>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding xLT}" />
<Setter Property="Canvas.Top" Value="{Binding yLT}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Canvas>
</StackPanel>
Usercontrol MyRectView 定義如下:
<UserControl x:Class="MVVM_TestRect.Views.MyRectView"
...
xmlns:vm="clr-namespace:MVVM_TestRect.ViewModels"
xmlns:local="clr-namespace:MVVM_TestRect.Views"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance vm:MyRectViewModel}"
Width="auto" Height="auto">
<Grid>
<Rectangle Width="{Binding Path=Width, Mode=TwoWay}"
Height="{Binding Path=Height, Mode=TwoWay}"
Fill="Green"/>
</Grid>
</UserControl>
該程序按方面工作,並且綁定似乎沒問題。
現在,如前所述,我將使用鼠標和移動/調整形狀的能力來實現繪圖。 我找到了很多例子,但沒有人能解決我的疑問:
MVVM 模式只是將視覺設計與應用程序數據結構分開的理想模式,所以當您說“MVVM 模式不允許將事件處理程序(用於鼠標交互)置於代碼隱藏視圖中”時,這可能過於激烈。 嘗試堅持下去以獲得更好的設計,但一開始不要太瘋狂。 看看這個頁面,它可能會很有趣。
WPF 在后面的代碼中自動為您創建事件處理程序,所以這就是它們的位置。 您可能想要做的是,而不是直接在事件處理程序中修改數據,將有一個 ViewModel,其方法將幫助您修改數據。
您可以使用與 Canvas 關聯的PreviewMouse(Up,Down,Move)事件。 這可能比嘗試單擊您的形狀更容易,特別是當多個形狀可能重疊時。 顯然,如果您有許多形狀,則必須有一種方法可以知道要編輯哪些形狀(通過 combobox 手動選擇,找到關閉形狀以單擊鼠標等)
從您的設計來看,可能會給您帶來麻煩的一個方面是您的 viewModel 管理1 個 shape 。 沒錯,但您需要另一個管理形狀集合的 VM 層。 它可以作為另一個 class 或作為 MyRectViewModel 中的一組MyRectViewModel
方法來完成:
void MyCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
MyShapeCollectionViewModel.StoreMouseDown(e);
}
void MyCanvas_PreviewMouseMove(object sender, MouseButtonEventArgs e)
{
MyShapeCollectionViewModel.ModifyShapes(e);
}
void MyCanvas_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
MyShapeCollectionViewModel.ModifyShapes(e);
}
ModifyShapes()
將計算鼠標拖動,找到要編輯的形狀並調用其編輯方法。 然后,一旦修改了 shape 數據,就會觸發相應的事件來更新關聯的 View
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.