У нас есть настраиваемый элемент управления, который имеет некоторую логику «фиксации» в событии LostFocus, которое срабатывает, если пользователь переходит в другую часть приложения.
Проблема возникает из-за того, что на панелях инструментов и в других областях приложения есть несколько кнопок, для которых свойство Focusable имеет значение False. Таким образом, когда они нажимаются, соответствующие действия срабатывают, но наш элемент управления еще не зафиксировал свои изменения, что вызывает проблемы.
Поскольку наш пользовательский интерфейс является модульным/динамическим по своей природе, и поскольку это просто хорошая практика кодирования, эти области не знают друг о друге, поэтому мы не можем просто добавить код в обработчики кнопок, чтобы наш элемент управления зафиксировался. Наш элемент управления должен вместо этого понимать, что было нажато что-то вне его.
Наша первоначальная попытка состояла в том, чтобы использовать обработчик событий уровня класса в GotFocus нашего элемента управления, например...
EventManager.RegisterClassHandler(
typeof(FrameworkElement),
PreviewMouseDownEvent,
new RoutedEventHandler(MyControl_PreviewMouseDownHandler));
private void MyControl_PreviewMouseDown(object sender, RoutedEventArgs e)
{
// Exit if the sender isn't the original source.
// This is because we want the deepest-clicked item, but also only want to process this once
if(sender != e.OriginalSource)
return;
var frameworkElement = (FrameworkElement)sender;
// If the clicked item is a descendant of ThisControl, do nothing.
if(frameworkElement.IsDescendantOf(NameOfMyControlInstance))
return;
CommitChanges();
// Unsubscribe class handler here
??? Can't do!
}
Если бы наш элемент управления потерял фокус, мы бы просто зафиксировали наши изменения и отменили подписку. Кроме того, если обработчик запущен, но OriginalSource находится вне нашего контроля, мы также зафиксируем наши изменения и отменим подписку обработчика. Проблема в том, что вы не можете отменить подписку на обработчики классов! Почему бы и нет, я понятия не имею.
Итак, как мы можем сказать, что пользователь щелкнул вне нашего контроля на что-то, что не перехватит фокус?
PropertyChanged
сDelay
(.NET 4.5 и выше). Не знаю, может ли это соответствовать вашему сценарию: конкретный вопрос - person Jcl   schedule 25.01.2016