簡體   English   中英

WPF - MVVM:如何用鼠標繪制可移動的矩形

[英]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 模式不允許將事件處理程序(用於鼠標交互)放在視圖代碼隱藏中,那么我應該在哪里編寫事件處理程序?
  • 由於缺少可能的交互(即按鈕向上、移動),MouseAction( 此處為 msdn 描述)似乎不合適; 我應該考慮哪些替代方案?
  • 鼠標交互應該由繪制形狀的地方還是由形狀本身處理?
  • MVVM 是用於此類應用程序的正確模式嗎?

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM