web-dev-qa-db-ja.com

ポップアップをToggleButtonに正しくバインドするにはどうすればよいですか?

ユーザーインターフェイスレベルからは比較的単純で論理的に見えることをしようとしていますが、非常に厄介なバグが1つあります。 ToggleButtonがあり、ボタンが切り替えられたときにPopupを表示し、ボタンが切り替えられたときにPopupを非表示にしようとしています。 Popupは、ユーザーがクリックして離れると非表示にもなります。

Popupが表示された後にトグルボタンをクリックすると、Popupが一瞬消えてから再び表示されることを除いて、次のXAMLではすべてが期待どおりに機能しています。

ここで何が起こっているのかというと、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>
21
craftworkgames

ステファンズの回答には、フォーカスを失うたびにポップアップを閉じるという望ましい動作も消えるという欠点があります。

ポップアップが開いているときにトグルボタンを無効にすることで解決しました。別の方法は、有効にする代わりに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");
    }
}
36
schoola

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>
24
Maxim Prasolov

ToggleButtonで、プロパティClickMode="Press"apixeltoofar を設定します

0
mikesl