2010-02-25 72 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>