Как открыть всплывающее окно WPF при нажатии другого элемента управления, используя только разметку XAML?

У меня есть два элемента управления: TextBlock и PopUp. Когда пользователь нажимает (MouseDown) на текстовом блоке, я хочу отобразить всплывающее окно. Я бы подумал, что могу сделать это с помощью EventTrigger в Popup, но я не могу использовать сеттеры в EventTrigger, я могу только начинать раскадровки. Я хочу сделать это строго в XAML, потому что два элемента управления находятся в шаблоне, и я не знаю, как найти всплывающее окно в коде.

Это то, что концептуально я хочу сделать, но не могу, потому что вы не можете поставить сеттер в EventTrigger (как вы можете с помощью DataTrigger):

Some text           ... 

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

Я сделал что-то простое, но оно работает.

Я использовал типичный ToggleButton, который я рестайлинг как текстовый блок, изменив его шаблон управления. Затем я просто привязал свойство IsChecked к ToggleButton к свойству IsOpen во всплывающем окне. В Popup есть некоторые свойства, такие как StaysOpen, которые позволяют изменять поведение закрытия.

В XamlPad работает следующее.

      Click Me Here!!      I'm the popup    

Следующий подход такой же, как и у Helge Klein, за исключением того, что всплывающее окно автоматически закрывается, когда вы нажимаете где-либо вне всплывающего windows (включая сам ToggleButton):

         

«BoolInverter» используется в привязке IsHitTestVisible, так что, когда вы снова нажимаете ToggleButton, всплывающее окно закрывается:

 public class BoolInverter : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is bool) return !(bool)value; return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return Convert(value, targetType, parameter, culture); } } 

… который показывает удобную технику объединения IValueConverter и MarkupExtension в одном.

Я обнаружил одну проблему с этой методикой: WPF глючит, когда одновременно появляются два всплывающих windows. В частности, если ваша кнопка переключения находится в «всплывающем всплывающем окне» на панели инструментов, после нажатия на нее откроется два всплывающих windows. Затем вы можете обнаружить, что второе всплывающее окно (ваше всплывающее окно) останется открытым, когда вы щелкните в другом месте в своем окне. В этот момент закрытие всплывающего windows затруднено. Пользователь не может снова нажать ToggleButton, чтобы закрыть всплывающее окно, потому что IsHitTestVisible является ложным, потому что всплывающее окно открыто! В моем приложении мне пришлось использовать несколько хаков для смягчения этой проблемы, например, следующий тест в главном окне, в котором говорится (в голосе Луи Блэка) «если всплывающее окно открыто и пользователь щелкает где-то вне всплывающего windows, закройте всплывающее окно «friggin».:

 PreviewMouseDown += (s, e) => { if (Popup.IsOpen) { Point p = e.GetPosition(Popup.Child); if (!IsInRange(pX, 0, ((FrameworkElement)Popup.Child).ActualWidth) || !IsInRange(pY, 0, ((FrameworkElement)Popup.Child).ActualHeight)) Popup.IsOpen = false; } }; 

У меня были некоторые проблемы с частью MouseDown, но вот какой-то код, который может начать работу.

          Test Popup Content                             

Как насчет:

     

Обратите внимание, что Popup окно ссылается на Button по имени и наоборот. Итак, x:Name="..." требуется как для Popup и для Button .

На самом деле его можно упростить, заменив материал Storyboard специальным действием SetProperty EventTrigger, описанным в этом SO-ответе

другой способ сделать это:

        
  • Выберите несколько элементов из DataGrid в проекте MVVM MVPM
  • Имя не существует в ошибке пространства имен в XAML
  • Связывание в текстовом столбце таблицы данных WPF
  • Объединить расширитель и сетку (изменяемый размер расширителя)
  • Есть ли ansible чит-лист WPF?
  • В чем разница между StaticResource и DynamicResource в WPF?
  • Где Application.DoEvents () в WPF?
  • Как извлечь шаблон управления по умолчанию в Visual Studio?
  • Каков наилучший способ передать событие в ViewModel?
  • Как программно установить выбранный элемент Panorama в WP7
  • DataTrigger, где значение НЕ равно нулю?
  • Давайте будем гением компьютера.