簡體   English   中英

WPF MVVM - 如何獲取 Canvas 上的鼠標坐標?

[英]WPF MVVM - How do I get the mouse coordinates on a Canvas?

我有一個 window 和一個 canvas(比 window 本身小)。 現在我想在單擊 canvas 時繪制一個矩形,它應該出現在我單擊的位置。 我讓它工作了,但是每當我點擊一個現有的矩形時,它似乎采用的是相對於現有矩形左上角的鼠標坐標,而不是 canvas 本身的坐標。 下面你會看到我的 XAML:

<ItemsControl ItemsSource="{Binding CanvasItems}" Grid.Column="1" >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas Background="White">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeftButtonDown">
                        <i:InvokeCommandAction Command="{Binding MouseButtonDownCommand}" PassEventArgsToCommand="True"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Canvas>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="Shape">
            <Setter Property="Canvas.Left" Value="{Binding ModelLeft}"/>
            <Setter Property="Canvas.Top" Value="{Binding ModelTop}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

在這里您可以在我的 ViewModel 中看到相應的命令方法:

private void OnMouseButtonDown(object obj)
    {
        var mouseArgs = obj as MouseButtonEventArgs;
        var point = mouseArgs.GetPosition((IInputElement)mouseArgs.Source);
        

        ModelLeft = (int)point.X;
        ModelTop = (int)point.Y;

        Rectangle rect = new Rectangle();
        
        
        rect.Stroke = new SolidColorBrush(Colors.Black);
        rect.Fill = new SolidColorBrush(Colors.Red);
        rect.Width = 200;
        rect.Height = 200;

        CanvasItems.Add(rect);
    }

為了更好地理解, ModelLeftModelTop是兩個 int 屬性,而CanvasItemsObservableCollection<object> 另外,我正在使用System.Windows.Shapes; 對於矩形。

我怎樣才能讓它按預期工作,它總是會使用相對於 canvas 的鼠標 position 而不是 canvas 上已經存在的形狀?

GetPosition返回相對於傳入元素左上角的鼠標坐標。因此,您可能只需將 canvas 本身傳遞給 mouseArgs.GetPosition,而不是點擊並引用mouseArgs.Source的 Shape 元素。

var point = mouseArgs.GetPosition(myCanvas);

您還可以使您的矩形對鼠標單擊“不可見”,這樣事件的來源將始終是您的 canvas。

rect.Width = 200;
rect.Height = 200;
rect.IsHitTestVisible = false;

此外,鼠標點擊有冒泡和隧道版本,要捕捉隧道版本,請處理 PreviewMouseDown 事件。 這樣,canvas 將始終有機會首先處理該事件。 但是,您仍然必須在 GetPosition 調用中將 canvas object 作為參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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