2011-06-10 14 views
3

シンプルなコードに問題があります。私は数時間の解決策を探していたが効果はなかった。 私はキャンバスと長方形を持っています。私はRectangleを移動します。カーソルが外側にある場合、pMouseMoveは各ピクセルに対して1回だけ発生します。逆に、カーソルがRectangleにある場合は、ピクセルごとに2回ディジェリーします。私は、それが矩形の外にあるかのように、一度だけ実行したい、それを行う方法?PreviewMouseMoveを2回実行する

XAML:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
    <Canvas x:Name="Can" Height="257" Width="503" Background="Gray"> 
    <TextBox Name="tb" Width="77" Height="20" Canvas.Left="0" Canvas.Top="-21"/> 
    </Canvas> 
</Window> 

コードビハインド:

public partial class MainWindow : Window 
{ 
    Rectangle rect = new Rectangle(); 
    private static int i; 
    private static string s; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     rect.Height = 50; 
     rect.Width = 50; 
     rect.Fill = Brushes.Black; 
     Can.Children.Add(rect); 
     Can.PreviewMouseMove += pMouseMove; 
    } 

    private void pMouseMove(object sender, MouseEventArgs e) 
    { 
     //cursor over Rectangle 
     Canvas.SetTop(rect, e.GetPosition(Can).Y + 10); 
     Canvas.SetLeft(rect, e.GetPosition(Can).X + 10); 

     //cursor outside Rectangle 
     //Canvas.SetTop(rect, e.GetPosition(Can).Y - 10); 
     //Canvas.SetLeft(rect, e.GetPosition(Can).X - 10); 

     //Counter 
     i++; 
     tb.Text = i.ToString(); 

     //e.Handled = true; 
    } 
} 

WPFの私の悪い英語

+0

マウスモーションイベントも時々はるかに少ない、画素毎に1よりも少ない頻繁に送信することができることをあなたは知っておく必要があります。パフォーマンスを気にするのは妥当ですが、正しさのために送信されたマウス移動イベントの数に依存するロジックはすべて破棄されます。 –

答えて

3

イベントのために申し訳ありませんが、効果的にあなたCanvasからイベントを受け取ることを意味し、Routed Eventsありますキャンバス自体とキャンバス内のすべてお気づきのように、CanvasPreviewMouseMoveイベントは、CanvasRectangleの両方からイベントを受信して​​います。

[更新] コードを実行して、e.OriginalSourceの値をチェックして、元々イベントを発生させた内容を確認しました。このように:

私のオリジナルの答えは、あなたが同じイベントを2回受け取っていたと思っていたので、e.OriginalSourceのタイプをチェックすることでした。しかし、私は今あなたが言っていることを見ている:e.OriginalSourceRectangleである場合、e.OriginalSourceCanvasである場合に比べてPreviewMouseMoveイベントが2回頻繁に発生する。これを行うRectangleの実装には内部的なものがあります(内部ロジックを見るためにReflectorのようなツールを使用することがわかります)。

あなたはrect.IsHitTestVisible = false;を設定することができ、それがイベントを送信し、e.OriginalSourceあることから四角形を解消します - それは、すべてのPreviewMouseMoveイベントがCanvasから来ることを意味しますので、あなたは、マウスの位置がRectangle内にあるかどうかを確認するために​​を使用することができます。

私はちょうどこのコードを次のように実行しました。これはイベントの一貫した発生を保証する方法だと思いますが、stiあなたのヒットテスト能力があります。 PreviewMouseMoveハンドラで

rect.Fill = Brushes.Black; 
rect.IsHitTestVisible = false; 
Can.Children.Add(rect); 

:コンストラクタで

private void pMouseMove(object sender, MouseEventArgs e) 
{ 
    // Debug.WriteLine(e.OriginalSource.ToString()); 

    HitTestResult result = VisualTreeHelper.HitTest(rect, e.GetPosition(sender as UIElement)); 

    if (result != null) { 
     Debug.WriteLine("Mouse inside rect") 
    } 
    else { 
     Debug.WriteLine("Mouse outside rect"); 
    } 
} 
+0

'e.OriginalSource'の値を確認しました。カーソルがRectangle上にある場合、 'pMouseMove'は2回発生し、どちらの場合も' e.OriginalSource'の値は 'System.Windows.Shapes.Rectangle'です。したがって、条件if(e.OriginalSourceはCanvas)は常にfalseです。 – Cinio

関連する問題