Борьба с внутренними методами WPF - PullRequest
0 голосов
/ 06 февраля 2019

ОБНОВЛЕНИЕ: Итак, у меня есть решение моей непосредственной проблемы.Мне не удалось создать "свой" класс TreeView.Но причина, по которой я хотел это сделать, заключалась в том, что элементы управления, основанные на ButtonBase, не работают в Popup из TreeView, и с помощью @MarkFeldman я нашел решение, которое приходит к нему отдругой угол.

Проблема состоит в том, что события MouseDown и MouseUp всплывают, и это переплетение пересекает границу логического дерева между Popup и его владельцем.Итак, когда вы нажимаете на что-то, размещенное внутри Popup, TreeViewItem и TreeView, которые в конечном итоге владеют Popup, узнают об этом.Затем он запускает код внутри TreeView, который проверяет «Есть ли у меня фокус?», А если нет, услужливо возвращает себе фокус - но, будучи отдельным логическим деревом, Popup имеетего собственный контекст фокуса, и поэтому он эффективно крадет фокус у элемента управления Button, когда он находится в середине обработки щелчка.Button реагирует на это, игнорируя щелчок.

Эта ошибочная обработка в TreeView происходит только при достижении событий MouseDown и MouseUp.Что если бы был какой-то способ помешать ему увидеть эти события?Что ж, если вы перехватываете события PreviewMouseDown и PreviewMouseUp и помечаете их Handled, то фреймворк не генерирует события MouseDown и MouseUp для начала.

Глядя на справочный источник, похоже, что обработка кликов ButtonBase связана с парой protected методов:

https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Primitives/ButtonBase.cs,414 https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Primitives/ButtonBase.cs,478

Это означает, что вы можете вызывать их из ваших собственных подклассов!Таким образом, вместо создания «своего» * ​​1045 *, где все элементы управления работают должным образом, вместо этого я могу создать «свой» CheckBox, который работает правильно в Popup из TreeView.Поскольку вся фактическая обработка кликов доступна напрямую, и события, которые она обычно отвечает на использование того же типа EventArgs, что и события Preview, и поверх нее обработка по умолчанию заботится о маркировкесобытия Handled, вся реализация сводится к следующему:

public class CheckBoxThatWorks : CheckBox
{
    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) => base.OnMouseLeftButtonDown(e);
    protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) => base.OnMouseLeftButtonUp(e);
}

Отлично!


ОРИГИНАЛЬНЫЙ ВОПРОС:

Мне нужно сделать клонкласса TreeView WPF - копия элемента управления, который работает из моего собственного кода.(В элементе управления есть ошибка, и Microsoft, похоже, не считает ее достаточно высоким приоритетом для исправления, и она делает невозможным размещение кнопок (включая флажки и переключатели) во всплывающих окнах, показанных в TreeViewItems. link )

Я столкнулся с серьезными трудностями из-за количества internal махинаций, которые Microsoft предприняла при реализации базовых элементов управления WPF.Несколько проблем, с которыми я столкнулся:

  • Элементы управления имеют свойство HandlesScrolling, которое позволяет им перенять базовую обработку прокрутки с ScrollViewer.Но он помечен internal, что делает для меня невозможным иметь собственный элемент управления, который самостоятельно обрабатывает прокрутку с клавиатуры.Я собирался сделать так, чтобы моя TreeView управляла прокруткой клавиатуры в OnPreviewKeyDown вместо OnKeyDown, чтобы он мог предотвратить возникновение событий KeyDown для клавиш, которые он перехватывает.Я не дошел до того, чтобы знать, какие предостережения могут быть по этому поводу.

  • Система визуальных состояний позволяет вам объявлять, какие стили следует применять при входе в разные состояния, но на самом делевходящие состояния, кажется, связаны виртуальным методом ChangeVisualState типа Control.Все элементы управления, которые хотят переключаться между визуальными состояниями, могут переопределять этот метод и проверять свое состояние, чтобы определить, какое визуальное состояние должно отображаться.Ой, подожди.Они не могут, потому что метод internal!Очевидно, только Microsoft может создавать элементы управления, которые устанавливают свои собственные визуальные состояния ??

Есть ли какие-либо стратегии, которые я могу использовать, чтобы обойти эти ограничения, или мне просто не повезло?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...