views:

677

answers:

2

Hi !

Suppose you have a ToggleButton for opening a Popup, same behaviour as all known elements as ComboBox etc.

... which is this code:

<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>

Then in code behind you work with .IsOpen for Popup and .IsChecked for ToggleButton. Everything works, but the problem arrives when you Open the Popup and click outside the borders. The Popup will be closed but the ToggleButton stays checked.

You cannot set in the PopupOnClosed Handler that ToggleButton.IsChecked = false, because when you Click on the ToggleButton to close the Popup, the Popup closes itself, sets ToggleButton.IsChecked = false but at the sime time you clicked on the ToggleButton and it tries to Open the Popup again. So you cannot close it.

1st ToggleButtonClick:

-> ToggleButton IsChecked = true

2nd ToggleButtonClick:

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

So if you click on the Toggle Button while Popup being open, it blinks but stays open.

How would you solve this problem, please ?

EDITED:

Try this in a MyWindow.XAML and add the dependency property IsDropDownOpen in the code behind, please:

<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));
A: 

Hi,

I would bind both guys to the same property in the ViewModel. You can find good example in Toolbox default template:

<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>

Hope this helps,

Cheers, Anvaka.

Anvaka
I've already tried this approach and the problem is this:1st ToggleButtonClick:>> ToggleButton IsChecked = true------2md ToggleButtonClick:>> ToggleButton IsChecked = false>> ToggleButton IsChecked = true-------So if you click on the Toggle Button while Popup being open, it blinks but stays open.
PaN1C_Showt1Me
+1  A: 

Ok, here is some code that works for me (those are copy-pasted from working code with some of the not-interesting parts removed):

Here's the content of a ComboBox-like UserControl:

<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>

And from a custom template to an actual ComboBox:

<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">
Nir
Oh well.. and the mystery has been revealed. ClickMode="Press" was the property that makes it WORK ! Thank you !
PaN1C_Showt1Me
I've got 1 more question: How do you ensure that the popup is closed automatically when clicking outside it, or when moving the whole window ?
PaN1C_Showt1Me