2016-04-18 29 views
3

私はItemsControlItemsPresenterMouseMoveイベントに応答しています。項目はデータソース内で移動され、アイテムが移動されたときにマウスがコントロール上にあると、マウスが動いていなくてもMouseMoveイベントが発生します。マウスが動いていないときにMouseMoveイベントが発生するのはなぜですか

以下は、この問題を示す例です。

XAML:

<ItemsControl Name="ladder" ItemsSource="{Binding Rows}"> 
    <ItemsControl.Template> 
     <ControlTemplate> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition /> 
       </Grid.RowDefinitions> 
       <TextBlock Text="Header" Grid.Column="0" /> 
       <ItemsPresenter Grid.Row="1" 
           MouseMove="OnMouseMove"/> 
      </Grid>     
     </ControlTemplate> 
    </ItemsControl.Template> 
</ItemsControl> 

C#が:あなたは、デバッグ/これを実行し、ItemsControlの上にマウスを移動し、そこにそれを残す場合は

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = this; 
     Rows.Add(new Row { Name = "0" }); 
     Rows.Add(new Row { Name = "1" }); 
     Rows.Add(new Row { Name = "2" }); 
     Rows.Add(new Row { Name = "3" }); 
     Rows.Add(new Row { Name = "4" }); 

     DispatcherTimer t = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(1000) }; 
     t.Tick += T_Tick; 
     t.Start(); 
    } 

    private void T_Tick(object sender, EventArgs e) 
    { 
     Rows.Move(4, 0); 
    } 

    private void OnMouseMove(object sender, MouseEventArgs e) 
    { 
     Debug.WriteLine(e.Timestamp); 
    } 

    public ObservableCollection<Row> Rows { get; set; } = new ObservableCollection<Row>(); 
} 

public class Row 
{ 
    public string Name { get; set; } 

    public override string ToString() 
    { 
     return Name; 
    } 
} 

、[出力]ウィンドウに表示されますMouseMoveイベントが制御シフトの項目として発生していることを示します。

これにはどのような理由がありますか?または、これらのイベントをフィルタリングして「本当の」マウス移動イベントにのみ応答する方法はありますか?

+1

マウスの視点から推測します。 – LarsTech

+0

しかし、マウスのコントロールではなく、コントロールの観点からのイベントですか? – WasGoodDone

+0

マウスの位置を同時に出力できますか?裸眼で見えない小さなマウスの動きがあるかもしれないが、コンピュータがピックアップしているのだろうか? –

答えて

3

これらのイベントは、アイテムプレゼンターの子コントロール、つまりTextBlocksからバブリングしています。あなたがこれを行う場合:

private void OnMouseMove(object sender, MouseEventArgs e) 
{ 
    var tb=(TextBlock)e.OriginalSource; 
    var lastMove = e.GetPosition((IInputElement)e.OriginalSource); 
    Debug.WriteLine(tb.Text + ":" + lastMove); 
} 

あなたは、イベントのたびに、元のソースが異なるテキストブロック(0 1 2 3 4 5)は、マウスの下に今あるテキストブロックであることがわかります。このテキストブロックの視点から、マウスは実際に移動しました。それはそれ以上ではなくなってしまいました。私はそれが議論の余地のある行動であることに同意し、おそらくはバグであると考えることもできます。これを回避するには、最後のマウスの移動位置を覚えておいて、それが変更されているかどうかを確認するのが最も簡単だと思います:

private Point _lastMove; 
private void OnMouseMove(object sender, MouseEventArgs e) 
{       
    var p = e.GetPosition((IInputElement)sender); 
    if (_lastMove != p) { 
     // really moved 
     _lastMove = p; 
    } 
} 
+0

ああ、そうですね。ありがとう! – WasGoodDone

関連する問題