Как правильно привязать всплывающее окно к ToggleButton?
Я пытаюсь сделать что-то, что кажется относительно простым и логичным с уровня пользовательского интерфейса, но у меня есть одна ошибка, которая очень раздражает. У меня есть ToggleButton
, и я пытаюсь показать Popup
, когда кнопка переключается и скрывает Popup
, когда кнопка переключается. Popup
также скрывается, когда пользователь нажимает на него.
Все работает как ожидалось со следующим XAML, за исключением случаев, когда я нажимаю кнопку переключения после отображения Popup
, исчезает Popup
в течение секунды секунды.
Я подозреваю, что здесь происходит то, что нажатие кнопки Popup
приводит к тому, что кнопка выключается, а затем сразу же после того, как кнопка переключается, когда щелчок мыши на ней. Я просто не знаю, как это исправить.
Любая помощь приветствуется. Спасибо.
<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" />
<Popup StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}">
<Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black">
<TextBlock>This is a test</TextBlock>
</Border>
</Popup>
Ответы
Ответ 1
Ответы Stephans имеют тот недостаток, что исчезает желаемое поведение закрытия всплывающего окна, когда оно теряет фокус.
Я решил это, отключив кнопку переключения, когда всплывающее окно открыто. Альтернативой было бы использовать свойство IsHitTestVisible, а не включено:
<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" IsEnabled="{Binding ElementName=ToggledPopup, Path=IsOpen, Converter={StaticResource BoolToInvertedBoolConverter}}"/>
<Popup x:Name="ToggledPopup" StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}">
<Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black">
<TextBlock>This is a test</TextBlock>
</Border>
</Popup>
Конвертер выглядит так:
public class BoolToInvertedBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool)
{
bool boolValue = (bool)value;
return !boolValue;
}
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException("ConvertBack() of BoolToInvertedBoolConverter is not implemented");
}
}
Ответ 2
Решение без IValueConverter:
<Grid>
<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" >
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="IsHitTestVisible" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Popup, Path=IsOpen}" Value="True">
<Setter Property="IsHitTestVisible" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Popup StaysOpen="false" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}"
PlacementTarget="{Binding ElementName=TogglePopupButton}" PopupAnimation="Slide"
x:Name="Popup">
<Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black">
<TextBlock>This is a test</TextBlock>
</Border>
</Popup>
</Grid>
Ответ 3
В ToggleButton установите свойство ClickMode="Press"
apixeltoofar
Ответ 4
Установите StaysOpen="True"
для Popup
Из MSDN:
Получает или задает значение, указывающее, закрывается ли элемент управления всплывающим окном когда элемент управления больше не находится в фокусе.
[...]
true
, если элемент управления Popup
закрывается, когда для свойства IsOpen
установлено значение false
;
false
, если элемент управления Popup
закрывается, когда событие мыши или клавиатуры происходит вне элемента управления Popup
.