У меня есть стандартный datagrid, определенный <Datagrid...> В этом datagrid у меня также есть стандартные "rowdetails", поэтому, когда нажата строка в datagrid, отображается деталь. Все работает так, как ожидалось.
Но, я в каждой строке в datagrid у меня есть кнопка <button..> на месте, и проблема в том, что при нажатии кнопки я не хочу, чтобы детали строки отображались. Если в строке щелкнуть где-нибудь еще, деталь должна быть правильно показана, но когда кнопка нажата, она должна делать только элементы кнопки, но не показывать детали строки.
Как это можно достичь?
До сих пор я пытался привязать событие PreviewMouseDown к кнопке, а затем по коду:
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var button = (Button) sender;
e.Handled = true;
}
Это правильно предотвращает показ детали строки datagrid при нажатии кнопки, но также не позволяет самой кнопке выполнить свой подключенный метод событий Click.
Все, что вам нужно сделать, это проверить, что пользователь UIElement
на самом деле нажал на свой обработчик OnPreviewMouseDown
:
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
IInputElement element = e.MouseDevice.DirectlyOver;
if (element != null && element is FrameworkElement)
{
Button button = GetParentOfType<Button>(element as FrameworkElement);
if (button != null)
{
// The Button was clicked
}
else e.Handled = true;
}
else e.Handled = true;
}
Метод GetParentOfType
представляет собой простую рекурсивную функцию, которая проверяет тип родителя каждого последующего UIElement
и возвращает ожидаемый тип, если он найден:
public T GetParentOfType<T>(DependencyObject element) where T : DependencyObject
{
Type type = typeof(T);
if (element == null) return null;
DependencyObject parent = VisualTreeHelper.GetParent(element);
if (parent == null && ((FrameworkElement)element).Parent is DependencyObject)
parent = ((FrameworkElement)element).Parent;
if (parent == null) return null;
else if (parent.GetType() == type || parent.GetType().IsSubclassOf(type))
return parent as T;
return GetParentOfType<T>(parent);
}
Угадывая здесь:
Могли бы вы, возможно, сделать поднятие строки нажатием кнопки после нажатия кнопки мыши. Например, MouseClickUp вместо OnMouseClick. И кнопка даже поднимается на OnMouseClick. Может быть, тогда обработчик кнопки называется первым и отклоняет событие строки?
Может быть, вместо использования кнопки вы могли бы использовать событие CellClick?