[英]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.