ToggleButton 控制 PopUp window 控件

ToggleButton controlling PopUp window control

我有一个由 ToggleButton 控制的 PopUp 控件。这工作正常,但是我不喜欢 ToggleButton 的出现,所以我应用了一个控制模板使 ToggleButton 看起来像 CheckBox。我希望在 PopUp 可见时检查 CheckBox,并在 PopUp window 消失时取消检查。我现在的代码如下,但是没有得到想要的效果

    <ToggleButton x:Name="LegendToggleButton" 
        HorizontalAlignment="Right" 
        IsChecked="{Binding IsOpen, ElementName=LegendPopup, mode=OneWayToSource}">
        <ToggleButton.Template>
            <ControlTemplate TargetType="ToggleButton">
                <CheckBox x:Name="LegendCheckBox" Content="Show Legend" Style="{StaticResource {x:Type CheckBox}}" 
                          IsChecked="{Binding IsOpen, ElementName=LegendPopup, Mode=TwoWay}" />
            </ControlTemplate>
        </ToggleButton.Template>
    </ToggleButton>

    <Popup x:Name="LegendPopup"
           PlacementTarget="{Binding ElementName=LegendToggleButton}"
           Placement="Top"
           PopupAnimation="Fade"
           StaysOpen="False">

这在单击切换按钮时显示 window 方面效果很好(CheckBox 被选中,然后在单击其他控件时取消选中并隐藏弹出窗口。但是,如果我通过单击切换按钮显示弹出窗口,然后再次单击切换按钮(我希望隐藏弹出窗口),弹出窗口会暂时关闭,然后立即重新出现。

为什么您希望 ToggleButton 看起来像 CheckBox 而不是只使用 Checkbox?下面的代码就像一个魅力:

<CheckBox x:Name="CheckBox" Content="Check me to open popup" />
<Popup IsOpen="{Binding ElementName=CheckBox, Path=IsChecked}">
    <Border Background="Silver" Padding="10">
        <TextBlock Text="Hello" />
    </Border>
</Popup>

如果您真的想使用您的解决方案,您应该按照 sondergard 在他的评论中建议的那样提供 "proper" 模板。我不太确定您是否可以将 CheckBox 作为 ToggleButton 的控制模板中的唯一元素嵌套。我至少要做的是在 CheckBox.IsCheckedToggleButton.IsChecked 属性 之间建立 TemplateBinding 以便它们同步。这也可能是导致奇怪行为的原因,因为您实际上有两个绑定到可以更新其 IsOpen 属性 的弹出窗口(一个在 ToggleButton,一个在 CheckBox 在控制模板中)。

我想出了一个解决方案,与我最初提出的问题略有不同,但以下代码提供了我正在寻找的功能。该方法涉及将 CheckBox IsChecked 和 PopUp IsOpen 属性 绑定到视图模型上的同一个布尔值,并在 CheckBox 失去焦点(隐藏 window 并更新选中的 CheckBox 属性)。

  • XAML:

    <Popup x:Name="LegendPopup"
           PlacementTarget="{Binding ElementName=LegendToggleButton}"
           Placement="Top"
           PopupAnimation="Fade"
           StaysOpen="False"
           IsOpen="{Binding ShowLegendPopup, Mode=OneWay}"
             >
    
  • c#视图模型

    private bool _showLegendPopup;
    public bool ShowLegendPopup
    {
        get
        {
            return _showLegendPopup;
        } 
        set
        {
            _showLegendPopup = value;
            OnPropertyChanged();
        }
    }
    
    public ICommand PopupClosingCommand { get; private set; }
    
    private void InitialiseCommands()
    {
        PopupClosingCommand =  new DelegatingCommand(PopupClosing);
    }
    
    private void PopupClosing()
    {
        ShowLegendPopup = false;
    }
    
IsChecked="{Binding IsOpen, ElementName=LegendPopup, mode=OneWayToSource}"

IsChecked="{Binding IsOpen, ElementName=LegendPopup, Mode=TwoWay}"

如果我是对的,这些就是罪魁祸首..

它实际上一次更改了两次 IsChecked 值..