События Canvas Click в Silverlight, когда они не находятся над UIElement

У меня есть объект холста, и я добавляю ему фантастические элементы управления. Я использую объект ScaleTransform для масштабирования холста, чтобы можно было увеличивать / уменьшать масштаб.

Я подключил элементы управления так, чтобы их можно было перетаскивать, и перетаскивание хорошо работает с помощью MouseLeftButtonDown, MouseLeftButtonUp и MouseMove. Теперь я хочу поработать над включением события, когда я нажимаю только на холст. Когда я читаю документы для объекта холста, я вижу, что событие MouseLeftButtonDown срабатывает только тогда, когда оно находится над UIElement.

Происходит при нажатии левой кнопки мыши (или когда кончик стилуса касается планшетного ПК), когда указатель мыши находится над UIElement. (Унаследовано от UIElement.)

К сожалению, мне нужно противоположное поведение. Я хочу знать, когда щелкают мышью по холсту, когда указатель мыши не находится над какими-либо элементами управления. Поскольку я новичок в Silverlight, я мог делать это неправильно. Я что-то упустил? Я ошибаюсь? Мне нужна небольшая помощь и, возможно, много указаний.


person Dan Wolchonok    schedule 09.06.2009    source источник


Ответы (4)


Я не гуру Silverlight, но не могли бы вы добавить прозрачный UIElement к Canvas под всеми другими UIElement и использовать его, чтобы определить, щелкнул ли пользователь за пределами любого из других элементов с возможностью перетаскивания / перетаскивания.

person Andrew Garrison    schedule 09.06.2009
comment
+1 @MichaelSync устанавливает прозрачный фон холста в отличие от значения по умолчанию {x: Null} для получения событий мыши. - person Dr. Andrew Burnett-Thompson; 23.03.2012
comment
Ха, да, было бы проще. Хорошее предложение, Майкл! - person Andrew Garrison; 25.03.2012
comment
Просто, красиво и чисто .. Молодец, чувак! @MichaelSync - person Avishek; 22.11.2012

Вы хотите знать, когда происходит щелчок по Canvas, а не над другими элементами управления?

Самое естественное - это захватить Canvas и MouseLeftButtonDown. Внутри этого события сделайте пик, чтобы увидеть, где произошел щелчок. Затем достигните UIElements под щелчком. Я рекомендую вам держать все в абсолютных координатах, чтобы все было прямо. Что-то типа:

void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Point p = e.GetPosition(null);
    var elements =  VisualTreeHelper.FindElementsInHostCoordinates(p, App.Current.RootVisual);
    foreach (var element in elements)
    {
        //Figure out if you're over a particular UI element
    }

}
person Erik Mork    schedule 09.06.2009
comment
Я думаю, что ваш ответ фантастический, но я не хочу циклически перебирать другие элементы управления на странице при нажатии кнопки мыши. Большое спасибо за полезный ответ. - person Dan Wolchonok; 13.06.2009

Я думаю, вы неправильно интерпретируете документацию. Согласно MSDN, Canvas сам по себе является реализацией UIElement:

System.Windows.UIElement
  System.Windows.FrameworkElement
    System.Windows.Controls.Panel
      System.Windows.Controls.Canvas

По моему опыту (и поправьте меня, если я ошибаюсь) MouseLeftButtonDown обычно срабатывает только для самого верхнего нажатого элемента UIElement. Поэтому, если вы реализуете MouseLeftButtonDown для своего Canvas, он должен срабатывать только при нажатии Canvas, а НЕ при нажатии кнопок. Я бы посоветовал сначала попробовать.

person Will Eddins    schedule 09.06.2009
comment
@guard, я видел обратное. Когда я включаю оба метода, они оба срабатывают, когда я нажимаю на UIElement, размещенный на холсте. - person Dan Wolchonok; 10.06.2009

Я думаю, что в WPF эту проблему легко решить с помощью перенаправленных событий. Однако Silverlight не получил этой функции. Вы можете проверить VisualTreeHelper.FindElementsInHostCoordinates. В этой статье это немного рассматривается.

http://www.andybeaulieu.com/Default.aspx?tabid=67&EntryID=95

person Jacob Adams    schedule 09.06.2009