Как реализовать воздушное сообщение в приложении WPF

Мы хотели бы использовать сообщения на воздушном шаре, как описано в Руководстве UX от Microsoft. Я нашел несколько примеров, в которых используется собственный код из Windows Forms, но нативный код требует дескриптора компонента, который немного сложнее для приложения WPF, поскольку он не соответствует той же концепции.

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

Конкретный случай, который у меня есть, представляет собой форму с несколькими текстовыми полями, которые нуждаются в проверке ввода и уведомлении о возможных неправильных входных значениях – что-то, что кажется подходящим для сообщений с воздушным шаром.

Есть ли коммерческий или открытый исходный код, созданный для этого варианта использования в WPF, о котором я должен знать?

Руководство UX указывает, что различия между баллоном и кончиком инструмента:

  • Воздушные шары могут отображаться независимо от текущего местоположения указателя, поэтому у них есть хвост, указывающий на источник.

  • Воздушные шары имеют название, основной текст и значок.

  • Воздушные шары могут быть интерактивными, тогда как невозможно щелкнуть кончиком.

Это последнее единственное значение для WPF. Если вам нужно, чтобы пользователь мог взаимодействовать с содержимым воздушного шара, тогда он должен быть всплывающим, а не всплывающей подсказкой. (Вы можете воспользоваться этим форумом, если поедете по этому маршруту.)

Но если все, что вы делаете, отображает уведомления, вы, безусловно, можете использовать подсказку. Вам также не нужно возиться с декораторами; просто создайте шаблон управления для всплывающей подсказки, которая будет выглядеть так, как вы хотите, создайте ресурс ToolTip, который использует этот стиль, и установите свойство ToolTip целевого ToolTip управления для этой ToolTip . Используйте ToolTipService чтобы контролировать, где он отображается относительно цели размещения.

Я пошел вперед и создал сайт CodePlex для этого, который включает в себя «Toast Popups» и контроль «Шары справки». Эти версии имеют больше возможностей, чем то, что описано ниже. Проект Code Plex .

Вот ссылка на пакет Nuget

Вот мое решение для заголовка шара. Некоторые из вещей, которые я хотел, чтобы они делали по-другому:

  • Затухание при входе мыши.
  • Затухайте, когда мышь уходит и закрывает окно, когда непрозрачность достигает 0.
  • Если мышь находится над окном, непрозрачность будет на 100%, а не закрыта.
  • Высота windows Balloon является динамичной.
  • Используйте триггеры событий вместо таймеров.
  • Поместите воздушный шар на левой или правой стороне элемента управления.

Screnshotвведите описание изображения здесь

Вот изображения справки, которые я использовал.

введите описание изображения здесьвведите описание изображения здесь

Я создал UserControl с простым значком «Справка».

   

И добавил это к коду позади.

 public partial class HelpBalloon : UserControl { private Balloon balloon = null; public HelpBalloon() { InitializeComponent(); } public string Caption { get; set; } public Balloon.Position Position { get; set; } private void ImageMouseEnter(object sender, MouseEventArgs e) { if (balloon == null) { balloon = new Balloon(this, this.Caption); balloon.Closed += BalloonClosed; balloon.Show(); } } private void BalloonClosed(object sender, EventArgs e) { this.balloon = null; } } 

Вот код XAML для windows шара, который открывается UserControl.

                                                               

И код позади windows Balloon.

 public partial class Balloon : Window { public enum Position { Left, Right } public Balloon(Control control, string caption, Position position) { InitializeComponent(); this.textBlockCaption.Text = caption; // Compensate for the bubble point double captionPointMargin = this.PathPointLeft.Margin.Left; Point location = GetControlPosition(control); if (position == Position.Left) { this.PathPointRight.Visibility = Visibility.Hidden; this.Left = location.X + (control.ActualWidth / 2) - captionPointMargin; } else { this.PathPointLeft.Visibility = Visibility.Hidden; this.Left = location.X - this.Width + control.ActualWidth + (captionPointMargin / 2); } this.Top = location.Y + (control.ActualHeight / 2); } private static Point GetControlPosition(Control control) { Point locationToScreen = control.PointToScreen(new Point(0, 0)); var source = PresentationSource.FromVisual(control); return source.CompositionTarget.TransformFromDevice.Transform(locationToScreen); } private void DoubleAnimationCompleted(object sender, EventArgs e) { if (!this.IsMouseOver) { this.Close(); } } } 

Я закончил тем, что помещал TextBlock в слой adorner:

             

Я также использовал всплывающую подсказку, как показано в каждом примере WPF:

       

Не оптимально (на самом деле это нужно для управления воздушным шаром), но работает достаточно хорошо для нас.

Я сделал предупреждающий баллон, чтобы решить проблему предупреждения Caps Lock в моем WPF-проекте.

введите описание изображения здесь

Если вы хотите добавить это предупреждение в свой проект, выполните следующие действия:

Добавить новое окно в ваш проект и указать имя «WarningBalloon».
Добавьте следующий код XAML в новое окно и добавьте значок предупреждения в папку изображений проекта.

                          Having Caps Lock on may cause you to enter your password incorrectly.   You should press Caps Lock to turn it of before entering your password. VerticalAlignment="Top" Width="346" FontSize="11"       

Введите следующий код за пределы LoginForm.

  private Point location; public static bool balloonVisFlag = false; private DispatcherTimer timer; WarningBalloon Balloon = null; private void ShowHideBalloon() { if (System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock)) { if (timer == null) { timer = new DispatcherTimer(); } location = GetControlPosition(psbPassword); Balloon.Left = location.X; Balloon.Top = location.Y; Balloon.Show(); balloonVisFlag = true; timer.Interval = TimeSpan.FromMilliseconds(5000); timer.IsEnabled = true; timer.Tick += new EventHandler(Timer_Tick); psbPassword.Focus(); } else { Balloon.Hide(); balloonVisFlag = false; psbPassword.Focus(); } } Point GetControlPosition(Control myControl) { Point locationToScreen = myControl.PointToScreen(new Point(0, 0)); PresentationSource source = PresentationSource.FromVisual(myControl); return source.CompositionTarget.TransformFromDevice.Transform(locationToScreen); } private void psbPassword_KeyDown(object sender, KeyEventArgs e) { ShowHideBalloon(); } private void Window_LocationChanged(object sender, EventArgs e) { if (balloonVisFlag == true) { ShowHideBalloon(); } } private void Timer_Tick(object sender, EventArgs e) { if (balloonVisFlag == true) { Balloon.Hide(); balloonVisFlag = false; } } } 

В нашем приложении мы реализовали воздушные шары как простое окно WPF. Расположение windows ограничено некоторыми свойствами родительской модели управления. Вот пример кода (где BalloonContainerWindow наследует от windows):

  BaloonContainterWindow newBalloon = new BaloonContainterWindow(); newBalloon.CreateBaloon(balloonType, balloonData); // Allow input and output when theis window is on top of winforms window SetBalloonLocation(newBalloon, sequenceId, stepId, rulerModel); newBalloon.Show(); newBalloon.CloseOnDeactivation = false; newBalloon.Activate(); 
  • Каковы некоторые из «лучших» кросс-платформенных инструментов C ++ UI сегодня?
  • Дизайн пользовательского интерфейса Blackberry - настраиваемый пользовательский интерфейс?
  • Отключить ключ ускорителя ярлыков WPF (текст подчеркивания отсутствует)
  • создание зачеркнутого текста?
  • Простая всплывающая форма java с по меньшей мере двумя полями
  • Редактор графического редактора Netbeans, создающий собственный непонятный код
  • GUI работает со скоростью 30 кадров в секунду?
  • Как получить центр большого пальца изображения UISlider
  • Разница между validate (), revalidate () и invalidate () в графическом интерфейсе Swing
  • Blackberry - Загрузка / Ожидание экрана с анимацией
  • Swing vs JavaFx для настольных приложений
  • Interesting Posts

    Простое регулярное выражение для десятичной дроби с точностью 2

    Можно ли запускать несколько виртуальных машин с независимой клавиатурой мыши + на одном ПК?

    Множественное наследование в java

    Как я могу изменить все настройки конфиденциальности Windows 10 без десятков кликов?

    разделители / разделители строк сетки андроида

    Почему мы не должны использовать защищенный static в java

    Как масштабировать / изменять размер текста в соответствии с TextView?

    подготовка файла mp4 для html 5

    Как проанализировать файл AndroidManifest.xml внутри пакета .apk

    Можно ли передать свойства как параметры «out» или «ref»?

    Учетная запись администратора повреждена?

    Вставить событие в текстовом поле WPF

    Эффективный C ++ Элемент 23 Предпочитайте функции, отличные от членов, не являющихся членами для функций-членов

    Как очистить / очистить кеш DNS в Google Chrome?

    Используйте LINQ для группировки последовательности чисел без пробелов

    Давайте будем гением компьютера.