2010-02-25 93 views
4

假设你有一个ToggleButton打开一个Popup,相同的行为,所有已知的元素ComboBoxWPF弹出隐藏的问题

...这是该代码:

<ToggleButton x:Name="PART_OpenToggleButton" 
    Focusable="False" 
    IsChecked="False" 
    Template="{StaticResource MyToggleButton}"> 
    <Grid>           
     <Popup x:Name="PART_PopupControl" 
       Style="{StaticResource MyPopupStyle}" 
       StaysOpen="False" 
       VerticalAlignment="Bottom" 
       IsOpen="False" 
       PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton, AncestorLevel=1}}" /> 
    </Grid> 
</ToggleButton> 
代码

那么后面你一起工作。 IsOpenPopup和。 IsChecked for ToggleButton。 一切正常,但当您打开Popup并点击边界外时,问题就会到达。 Popup将被关闭,但ToggleButton停留检查

你不能在PopupOnClosed处理器是ToggleButton.IsChecked = false设置,因为当你点击ToggleButton关闭Popup,在Popup自行关闭,设置ToggleButton.IsChecked = false但在森那一次你点击了ToggleButton尝试打开再次Popup。所以你不能关闭它。

1 ToggleButtonClick:

-> ToggleButton IsChecked = true 

第二ToggleButtonClick:

-> ToggleButton IsChecked = false 
-> ToggleButton IsChecked = true 

所以,如果你点击切换按钮,同时弹出是开放的,它闪烁但保持打开状态。

请问您如何解决此问题?

编辑:

在MyWindow.XAML试试这个,在代码添加依赖属性IsDropDownOpen 后面,请:

<Grid> 
     <ToggleButton x:Name="PART_OpenToggleButton" 
         Focusable="False"       
         Height="20" 
         Width="50" 
         IsChecked="{Binding ElementName=TestWindow, Mode=TwoWay, Path=IsDropDownOpen}"> 
      <Grid> 

       <Popup x:Name="PART_PopupControl" 
         Width="100" 
         Height="100" 
         StaysOpen="False" 
         Focusable="False" 
         VerticalAlignment="Bottom" 
         IsOpen="{Binding ElementName=TestWindow, Path=IsDropDownOpen}" 
         PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton, AncestorLevel=1}}">     
       </Popup> 
      </Grid> 
     </ToggleButton> 
    </Grid> 

public bool IsDropDownOpen 
     { 
      get { return (bool)GetValue(IsDropDownOpenProperty); } 
      set { SetValue(IsDropDownOpenProperty, value); } 
     }   
     public static readonly DependencyProperty IsDropDownOpenProperty = 
      DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(Window), new UIPropertyMetadata(false)); 
+0

取看看:http://stackoverflow.com/questions/13687463/wpf-popup-staysopen-false-still-keep-the-popup-open-while-clicking-outside – SepehrM 2015-01-25 17:23:19

回答

0

我想你们都绑定到同一属性ViewModel。您可以在工具箱中的默认模板找到很好的例子:

<ToggleButton x:Name="OverflowButton" 
      FocusVisualStyle="{x:Null}" 
      IsEnabled="{TemplateBinding HasOverflowItems}" 
      Style="{StaticResource ToolBarHorizontalOverflowButtonStyle}" 
      IsChecked="{Binding Path=IsOverflowOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" 
      ClickMode="Press"/> 
    <Popup x:Name="OverflowPopup" 
     AllowsTransparency="true" 
     Placement="Bottom" 
     IsOpen="{Binding Path=IsOverflowOpen,RelativeSource={RelativeSource TemplatedParent}}" 
     StaysOpen="false" 
     Focusable="false" 
     PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"> 
     <theme:SystemDropShadowChrome Name="Shdw" Color="Transparent"> 
      <Border Background="{StaticResource ToolBarSubMenuBackground}" 
        BorderBrush="{StaticResource ToolBarMenuBorder}" 
        BorderThickness="1"> 
       <ToolBarOverflowPanel x:Name="PART_ToolBarOverflowPanel" 
            Margin="2" 
            WrapWidth="200" 
            Focusable="true" 
            FocusVisualStyle="{x:Null}" 
            KeyboardNavigation.TabNavigation="Cycle" 
            KeyboardNavigation.DirectionalNavigation="Cycle" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
      </Border> 
     </theme:SystemDropShadowChrome> 
    </Popup> 

希望这有助于

干杯,Anvaka。

+0

我已经试过这个方法和问题是这样的: 1 ToggleButtonClick: >>切换按钮=器isChecked真正 ------ 为2Md ToggleButtonClick: >>切换按钮=器isChecked假 >>切换按钮=器isChecked真正 ----- - 因此,如果您在弹出窗口打开时单击切换按钮,它会闪烁但保持打开状态。 – 2010-02-25 12:55:27

2

好吧,这里是一些代码,对我的作品(这些都是从一些去除未有趣的部分工作代码复制粘贴):

这里有一个组合框状的用户控件的内容:

<ToggleButton x:Name="Button" Height="19"> 
    <Grid> 
     <Label Name="DisplayList" Content="Whatever" /> 
     <Popup Name="SelectionPopup" MinHeight="100" MinWidth="200" 
        StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=Button}"> 
     </Popup> 
    </Grid> 
</ToggleButton> 

而从自定义模板,以实际组合框:

<ToggleButton 
     Name="ToggleButton" 
     Template="{StaticResource ComboBoxToggleButton}" 
     Grid.Column="2" 
     Focusable="false" 
     IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" 
     ClickMode="Press"> 
</ToggleButton> 
<Popup 
     Name="Popup" 
     Placement="Bottom" 
     IsOpen="{TemplateBinding IsDropDownOpen}" 
     AllowsTransparency="True" 
     Focusable="False" 
     PopupAnimation="Slide"> 
+1

噢,以及这个谜已被揭示。 ClickMode =“Press”是使它工作的属性!谢谢 ! – 2010-03-02 08:58:37

+1

我还有1个问题:如何确保弹出窗口在点击外部时自动关闭,或者在移动整个窗口时自动关闭? – 2010-03-02 09:00:24

+0

Hi @ PaN1C_Showt1Me,你到底是怎么解决这个问题的?使用上面的“ClickMode = Press”解决方案,我看到了与Popup在外部点击时保持打开状态相同的问题吗? – HipsterZipster 2013-02-11 16:06:12

2

我发现这个职位的解决方案:https://stackoverflow.com/a/5821819/651161

使用以下类将允许在按下togglebutton之前处理点击。弹出窗口因点击而关闭,但点击被处理,因此不会触发ToggleButton点击。

public class MyPopup : Popup { 
    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) { 
     bool isOpen = this.IsOpen; 
     base.OnPreviewMouseLeftButtonDown(e); 

     if (isOpen && !this.IsOpen) 
      e.Handled = true; 
    } 
} 
+0

这终于解决了我的问题,并且是我认为的最简单的解决方案。 – 2013-10-08 13:35:44

+0

不适合我。 – 2016-05-31 19:05:55

1

您可以在弹出窗口StaysOpen财产只是绑定到按钮IsMouseOver财产。这样,只要您点击弹出窗口外的某个东西(IsMouseOver = false = StaysOpen),弹出窗口就会关闭,并在单击ToggleButtonIsMouseOver = true = StaysOpen)时关闭弹出窗口。 这样,即使Popup外部的点击也会被处理。

<ToggleButton x:Name="Toggle" /> 
<Popup x:Name="Popup" IsOpen="{Binding ElementName=Toggle, Path=IsChecked, Mode=TwoWay}" 
StaysOpen="{Binding ElementName=Toggle, Path=IsMouseOver}" /> 
+0

这对我来说没有其他修补程序可以工作。 – 2017-11-26 10:46:49

1

在我看来,有两个问题 - 之一是ADRESS的问题,即弹出里面点击根据它在视觉树中的位置可能再次处理。

第二个问题是 - 通过点击自动关闭 - 每次在弹出窗口外单击时都会发生,并且可能会触发其他事件。即使您点击“打开按钮”关闭。问题是 - 您不知道在popup.isOpen之前设置了哪个值 - 因为打开按钮的单击事件处理程序始终为false。

我不使用toggleButton来节省内存,但我认为关键问题是一样的。 toggleButton在你点击它时已经是假的。

我的例子弹出的定义那样:

<Popup Placement="Bottom" PopupAnimation="Slide" Name="PART_Popup" VerticalOffset="3" AllowsTransparency="True" StaysOpen="False"> 

如果你点击放置目标 - 这是“打开按钮”弹出关闭,同时按钮的点击事件处理但popup.IsOpen属性已经是'假' - 所以它再次打开。

我做了什么来解决这个问题,是订阅弹出窗口“关闭”事件,保存时间阻止重新打开一秒钟。

DateTime? LastClose = new DateTime?(); 

private void Popup_Closed(object sender, EventArgs e) 
{ LastClose = DateTime.Now; } 

public bool AllowReopen 
{ 
    get { 
      if ((popup == null) || (popup.IsOpen)) return false; 
      //You cannot open, when the template isn't applied or it is already open 

      return !LastClose.HasValue || (DateTime.Now - LastClose.Value) > new TimeSpan(0,0,1) /*1s*/; 
     } 
} 


public void OpenPopup() 
{ 
    if (!AllowReopen) return; 

    popup.IsOpen = true; 
} 
0

要防止通过单击其背景来关闭Popup,请插入将填充Popup的内容。

在这个例子中,点击未填充空间将关闭弹出:

<Popup x:Key="MyPop" Width="200" Height="200" StaysOpen="False">    
       <CheckBox Content="abc" /> 
</Popup> 

在这个例子中,点击未填充空间不会关闭弹出:

<Popup x:Key="MyPop" Width="200" Height="200" StaysOpen="False"> 
     <StackPanel Background="Red" Width="200" Height="200"> <!--EXTRA PANEL --> 
       <CheckBox Content="abc" /> 
     </StackPanel> 
</Popup>