Как сделать всплывающее окно wpf
Добавил пользователь Дмитрий К. Обновлено: 11.09.2024
Я've получили два элемента управления TextBlock и всплывающее окно. Когда пользователь нажимает кнопку (событие mousedown) на объект TextBlock, я хочу, чтобы отобразить всплывающее окно. Я думаю, что я мог бы сделать это с EventTrigger на popup, но я могу'т использовать сеттеры в EventTrigger, я могу только начать раскадровки. Я хочу сделать это строго в XAML, потому что два управления в шаблоне и я не'т знаю, как я'й найдешь появившемся в код.
Это то, что концептуально я хочу сделать, но может't, потому что вы можете'т поставить сеттер в EventTrigger (например, вы можете с помощью DataTrigger):
Что является лучшим способом, чтобы показать всплывающее строго в XAML, когда событие происходит на другой элемент управления?
Я сделал что-то просто, но это работает.
Я использовал обычный выключатель, который я рестайлинг в элементе TextBlock, меняя свой шаблон. Тогда я просто привязан свойство ischecked на выключатель на свойства isopen всплывающего окна. Всплывающее окно имеет некоторые свойства, такие как StaysOpen, которые позволяют изменять закрытия.
Следующие работы в файла.
Следующий подход такой же, как и Хельге Кляйн's, за исключением того, что всплывающее окно закрывается автоматически, когда вы щелкните за пределами всплывающего окна (включая сам выключатель):
назальный BoolInverter; используется в IsHitTestVisible привязки, так что, когда вы снова нажмите выключатель, всплывающее окно закрывается:
Я обнаружила одну проблему с этой техникой: в WPF глючит, когда два окна на экране одновременно. В частности, если ваш выключатель о "переполнение всплывающее окно" в панели инструментов, то будут два всплывающие окна открываются после нажатия на нее. Затем вы можете обнаружить, что второй всплывающего (контекстного) будет оставаться открытым, когда вы щелкните в любом месте на вашем окне. В этот момент, закрывая всплывающее сложно. Пользователь не может повторно нажмите на выключатель, чтобы закрыть всплывающее окно, потому что IsHitTestVisible является ложным, потому что раскрывается! В мое приложение я должен использовать несколько хаков, чтобы смягчить эту проблему, например, следующий тест на главное окно, в котором написано (в голосе Луи черный) "если всплывающее окно открыто, и пользователь щелкает где-то за пределами всплывающего окна закройте, блин' всплывающее окно.&я:
Прежде, чем я получу нормальные стоны о том, чтобы сделать это "правильно".
-
Я не писал приложение, просто поставил задачу повысить производительность (и/или восприятие производительности) без полного перерасхода. В какой-то момент я надеюсь, что я смогу изменить инструмент для этого приложения, пока на него не будут исправлены небольшие хитрости. Нет кода ViewModel. действительно, действительно связан с пользовательским интерфейсом. (Как я уже сказал, я не был прав в приложении) По разным причинам я не могу использовать потоки в этом сценарии, не нарушая слишком много других peices в приложении и мои временные ограничения.
Итак, есть ли способ сделать это в этом сценарии (btw. нет ViewModel, и я не могу создать его прямо сейчас из-за жесткой связи Logic-UI)?
Я просто хочу открыть WPF Popup с задержкой, вроде ToolTip.
Как я могу это достичь?
И, кстати, Popup.PopupAnimation = PopupAnimation.Fade. затухает слишком быстро. Я хочу, по крайней мере, на полсекунды.
ОТВЕТЫ
Ответ 1
Сначала. кредит для этого ответа идет на Эрик Берк. Он ответил на этот вопрос, размещенный в группе WPF Disciples. Я подумал, что было бы полезно поставить этот ответ на StackOverflow тоже.
В принципе, вам нужно оживить свойство IsOpen всплывающего окна с помощью DiscreteBooleanKeyFrame.
Обратите внимание на следующий xaml (который можно легко вставить в Kaxaml или другую свободную утилиту редактирования xaml):
Обратите внимание, что я немного изменил свое первоначальное решение. чтобы вызвать IsOpen на мыши, вместо проверки CheckBox, как и у него. Все в попытке заставить Popup вести себя немного как ToolTip.
Ответ 2
Вы можете создать стиль, который будет применен к Popup следующим образом:
Затем, всякий раз, когда вы хотите использовать его, вы будете писать разметку, подобную этой (обратите внимание на привязку для PlacementTarget):
Ответ 3
Вложенный ответ cplotts хорош, но может не применяться в вашем случае, потому что он оставляет анимацию, прикрепленную к свойству IsOpen, эффективно блокируя ее на месте и предотвращая ее изменение с помощью настройки прямого свойства, привязки и других способов. Это может затруднить использование вашего кода в зависимости от того, как вы его используете.
Если это так, я бы переключился на запуск DispatcherTimer, когда вы хотите открыть всплывающее окно после некоторой задержки, например:
Для поведения типа ToolTip это можно сделать на MouseEnter. Если вы хотите отменить всплывающее окно по какой-либо причине (например, если мышь покидает элемент управления до появления всплывающего окна), просто:
Обновление
Так как cplotts, рассмотренные в комментарии, вы также захотите установить _popup.IsOpen = false в некоторых ситуациях в событии MouseLeave, в зависимости от вашей логики для обработки событий ввода/вывода мыши между вашим элементом управления и всплывающим окном. Имейте в виду, что вы обычно не хотите слепо устанавливать IsOpen=false в каждое событие MouseLeave, потому что это может произойти, когда всплывающее окно появляется над ним. В некоторых ситуациях это приведет к появлению мерцающего всплывающего окна. Поэтому вам понадобится какая-то логика.
Ответ 4
Ответ 5
Вы можете расширить XAML для этого решения, чтобы всплывающее окно оставалось открытым, пока мышь над ним, затем автоматически исчезает.
Я модифицировал образец следующим образом:
- Создайте анимацию "ClosePopop", которая устанавливает IsOpen в False через 0,5 секунды. Я сделал это ресурсом, потому что он использовался дважды.
- Для управляющего триггера IsMouseOver добавьте ExitAction, который запустит анимацию ClosePopup. Это дает пользователю возможность переместить указатель мыши над всплывающим окном, прежде чем он закроется. Я назвал эту анимацию "bxb"
- Добавить триггер для всплывающего свойства IsMouseOver. На mouseover остановите (но не удаляйте) оригинальную анимацию Closexopup "bxb". Это оставляет всплывающее окно видимым; удаление анимации здесь приведет к закрытию всплывающего окна.
- В выпадающем меню мыши запустите новую анимацию ClosePopup и удалите анимацию "bxb". Последний шаг критический, потому что в противном случае первая, остановленная анимация "bxb" сохранит всплывающее окно.
Эта версия превращает синюю попку, пока мышь над ней, чтобы вы могли видеть последовательность событий с помощью Kaxaml.
В данный Frame я выгружаю различные представления.
В данный Frame я выгружаю различные представления.
Можно же просто бэкграунд окна сделать прозрачным и черным, вот и будет затемнение
что-то вроде такого:
Можно же просто бэкграунд окна сделать прозрачным и черным, вот и будет затемнение
что-то вроде такого:
Control (Theme resource):
Вот прозрачный затемненный фон, который блокирует все что сзади и непрозрачные контролы на нем, по которым можно щелкать.
Или я неправильно понял?
Поскольку содержание устарело, вместо этой статьи была написана новая статья, пожалуйста, обратитесь к новой статье:
В этой статье рассматриваются элементы пользовательского интерфейса и поведение стандартного окна. Окно (форма) является одним из наиболее часто используемых элементов пользовательского интерфейса, будь то настольное программирование или повседневное использование. Поскольку Window так важен и важен, его понимание не причиняет вреда.
Представьте принцип и различные детали использования WindowChrome для настройки Window.
Поскольку в родном окне WPF в RibbonWindow есть много ошибок в пользовательском интерфейсе, я предоставил настраиваемое окно RibbonWindow для решения этих проблем.
1. Введение
- Было бы ужасно, если бы в Window не было теней, но добавление DropShadowEffect в одиночку сильно повлияло бы на производительность.
- Потребность настроить всплывающее окно, закрыть, развернуть, свернуть анимацию и сделать это самостоятельно, безусловно, не так эффективна, как собственная анимация Windows.
- Необходимо реализовать функцию изменения размера.
- Другие ошибки
2. Основные оконные функции
Я хочу добиться эффекта окна, похожего на Office 2016: тени, пользовательские цвета форм. Для теней и анимационных эффектов вы можете оставить системные настройки по умолчанию, которые в основном будут выглядеть хорошо.
Большинство пользовательских окон имеют закругленные углы, но мне это не нравится. Закругленные углы с несколькими пикселями обычно не очень закруглены при низком DPI (см. Рисунок ниже), поэтому сохраняйте правильные углы.
Кроме того, цвет строки заголовка изменяется в активном и неактивном состояниях:
Конечный результат выглядит следующим образом:
3. Осознать
3.1 Определите элемент управления CustomWindow
Во-первых, чтобы облегчить будущее расширение, я определил шаблонный элемент управления с именем CustomWindow, полученный из Window.
В основном добавлено несколько CommandBindings для кнопок привязки в строке заголовка.
3.2 Использование WindowChrome
Для WindowChrome,MSDNЭто описано так:
Чтобы настроить окно, сохранив его стандартные функции, вы можете использовать класс WindowChrome. Функциональность WindowChrome-подобной оконной рамки разделяет визуальные объекты и позволяет контролировать границу между клиентом и нерабочей областью окна приложения.
Добавьте следующие параметры в DefaultStyle CustomWindow:
В дополнение к границе, содержащей тень, содержимое всего окна может быть задано пользователем.
3.3 Базовое расположение окон
Стандартный макет окна прост, примерно строка заголовка и содержание.
PART_WindowTitleGrid - строка заголовка, конкретный контент будет обсуждаться в следующем разделе.
Содержимое ContentPresenter является клиентской областью окна.
ResizeGrip это когда ResizeMode = ResizeMode.CanResizeWithGrip; Дескриптор изменения размера в нижнем правом углу окна, который появляется, когда окно в основном используется для запроса окна, можно изменить, перетаскивая границу.
3.4 Строка заголовка макета
Кнопки в строке заголовка реализованы, как указано выше, привязывают Command к SystemCommands и устанавливают WindowChrome.IsHitTestVisibleInChrome="True" Содержимое в строке заголовка должно устанавливать это дополнительное свойство, чтобы реагировать на операции мыши.
Значок в строке заголовка также является кнопкой. Автономно открывает SystemMenu и дважды щелкает, чтобы закрыть окно. Значения высоты и ширины используются отдельно SystemParameters.SmallIconHeight и SystemParameters.SmallIconWidth SystemParameters содержит атрибуты, которые можно использовать для запроса настроек системы. Всегда правильно использовать SystemParameters везде, где это возможно.
Стиль кнопки реализован не очень хорошо, это будет немного пока, и это будет улучшено в будущем.
3.5 Обработка триггеров
Хотя мне обычно нравится использовать VisualState для реализации перехода между пользовательским интерфейсом шаблонного элемента управления и состоянием, иногда триггер удобен и быстр, особенно когда анимация не нужна.
Обратите внимание, что когда WindowState = Maximized, Margin of LayoutRoot должен быть установлен на 7. Если вы этого не сделаете, край окна будет замаскирован при максимизации. Многие решения, использующие WindowChrome для настройки окна, недоступны. Смирись с этим.
3.6 Управление навигацией
Еще один момент, на который стоит обратить внимание, это клавиатурная навигация. В общем, если вы нажимаете клавишу Tab в окне, фокус будет циклически перемещаться по содержимому окна. Не позволяйте кнопкам в строке заголовка получить фокус и не позволяйте родительским элементам ContentPresenter получить фокус, поэтому установите его на ContentPresenter KeyboardNavigation.TabNavigation="Cycle" , Чтобы кнопки в строке заголовка не фокусировались, они также установлены на каждой кнопке IsTabStop="False" ,
3.7 DragMove
Некоторым людям нравится больше, чем просто строка заголовка. Вы можете перетащить Окно, удерживая любую пустую часть окна, просто добавьте DragMove в свой код:
3.8 Портирование Переходя ContentControl
Просто позвольте содержанию окна также добавить анимацию. Я буду Silverlight Инструментарий TransitioningContentControl Скопируйте его, только немного измените анимацию и OnApplyTemplate() Наконец добавил это предложение: VisualStateManager.GoToState(this, Transition, true); , Наконец, замените ContentPresenter в Window этим элементом управления, эффект не плохой (реальный эффект довольно плавный, но GIF выглядит не очень хорошо):
3.9 Проблема SizeToContent
Существует более неприятная проблема при настройке SizeToContent="WidthAndHeight" Когда вы откроете Window, вы получите следующую ошибку.
Кажется, что размер содержимого и размер окна рассчитаны неправильно.В настоящее время решение заключается в добавлении следующего кода в CustomWindow, который прост и груб, но может вызвать другие проблемы:
5. Заключение
В первый раз, когда я написал стиль Window, я не мог придумать так много мест, на которые стоит обратить внимание
В настоящее время это очень простая демонстрация, без добавления дополнительных функций, надеюсь, она будет полезна другим.
Кодировка выполняется в Window10 и только немного протестирована в Windows7, я не смею гарантировать совместимость.
Пожалуйста, укажите на любые ошибки или упущения.
Читайте также: