【问题标题】:WPF popup staysopen=false still keep the popup open while clicking outsideWPF popup staysopen=false 在点击外部时仍然保持弹出窗口打开
【发布时间】:2012-12-03 16:23:42
【问题描述】:

我的问题是我在弹出窗口中创建了一个列表框,并设置了弹出窗口的staysopen=false。但是每次弹出框弹出时,我都必须单击弹出框内的某些内容(例如在列表框中选择一个元素),然后单击弹出框外部,它会自动关闭。如果我不点击任何东西,即使我点击弹出窗口之外的其他元素,弹出窗口也会保持打开状态。我需要关闭弹出窗口而不需要我单击其中的任何元素。我能做些什么?这是代码,还有一些其他样式链接到此代码,但只是一些颜色样式。

我的控制是当用户单击弹出框顶部的文本框时,列表框会弹出。如果用户什么都不做并单击此元素之外的任何位置,则弹出框将关闭。谢谢。

我可以使用下面的代码在 Silverlight 中完成它。但似乎在 wpf 中,它不再工作了。

popupAncestor = FindHighestAncestor(this.ListBoxPopup); if (popupAncestor == null) { return; } popupAncestor.AddHandler(System.Windows.Controls.Primitives.Popup.MouseLeftButtonDownEvent, (MouseButtonEventHandler)ClosePopup, true);

<Grid x:Name="MainGrid" Margin="0" VerticalAlignment="Center">
    <Grid.RowDefinitions>
        <RowDefinition Height="20"></RowDefinition>
        <RowDefinition Height="auto"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid Margin="1,1,1,0" x:Name="TopBar"  Visibility="Visible"  Grid.Row="0" Height="20" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="{StaticResource COL_BTN_LIGHT}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="19"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="TextBoxSearchItem"  x:FieldModifier="private" HorizontalAlignment="Stretch" Grid.Column="0" VerticalAlignment="Stretch" BorderThickness="0,0,0,0" Background="Transparent" TextChanged="TextBoxSearchItem_TextChanged"></TextBox>
        <ToggleButton x:Name="DropDownArrorButton" Grid.Column="1" Style="{StaticResource ComboBoxReadonlyToggleButton}"></ToggleButton>
        <!--<TextBlock HorizontalAlignment="Center" Text="Search" Grid.ColumnSpan="2" TextBlock.FontStyle="Italic" Opacity="0.4" VerticalAlignment="Center"/>-->
    </Grid>
    <Grid Grid.Row="1" HorizontalAlignment="Stretch" x:Name="PopupGrid"  Margin="0,1,0,0" >
        <Popup x:Name="ListBoxPopup" StaysOpen="False" x:FieldModifier="private"  IsOpen="{Binding ElementName=DropDownArrorButton, Path=IsChecked, Mode=TwoWay}" 
               AllowsTransparency="true" Margin="0" HorizontalAlignment="Stretch" Placement="Bottom" 
               PlacementTarget="{Binding ElementName=TopBar}"  Opened="OnPopupOpened" Closed="OnPopupClosed"
               HorizontalOffset="{Binding ElementName=PopupGrid, Path=Value, Mode=TwoWay}"
                 VerticalOffset="{Binding ElementName=PopupGrid, Path=Value, Mode=TwoWay}">
            <ListBox x:Name="ListBoxContainer" Width="{Binding ElementName=MainGrid, Path=ActualWidth}" 
                     HorizontalContentAlignment="Stretch" SelectionMode="Single"  Height="200"  Margin="0" 
                     SelectionChanged="ListBoxContainer_SelectionChanged"
                     MouseDoubleClick="ListBoxContainer_MouseDoubleClick">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid HorizontalAlignment="Stretch">
                            <Border BorderBrush="{Binding SearchedBackColor}" BorderThickness="{Binding Indicator}" Width="{Binding ElementName=MainGrid, Path=ActualWidth}">
                                <TextBlock x:Name="ContentText" Text="{Binding Name}" Margin="1,0,0,0"/>
                            </Border>                               
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Popup>                
        <Border x:Name="listBorder" BorderBrush="{StaticResource COL_BTN}" BorderThickness="0,1,0,0" ></Border>     
    </Grid>                 
</Grid>

【问题讨论】:

  • 您是否尝试过在弹出窗口显示时自动将焦点集中在某些内容上?
  • 什么控件托管弹出窗口以及它是如何显示的?
  • 1 - 发布您的 XAML。 2 - 发布您的代码。
  • 我使用网格来托管弹出窗口,在网格上方,有一个文本框,就像一个可编辑的组合框。但我需要更灵活的控制,所以我没有使用组合框。
  • 为什么?您可以独立控制所选项目和项目列表的内容。如果需要,项目列表可以是 2x5 的复选框网格。

标签: c# wpf xaml


【解决方案1】:

您应该在视图模型或控件中为“IsPopupOpen”创建一个依赖属性,如下所示,以管理弹出窗口的状态。然后您可以将 ToggleButton "IsChecked" 和弹出窗口 "IsOpen" 绑定到该 DP。

同样在您的 ToggleButton 上,设置“Focusable=false”和“IsThreeState=false”

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

祝你好运!

【讨论】:

  • 我让用户控件继承了组合框并重新设置了组合框的样式并完成了它,谢谢大家。
  • 嗨 Lance,很高兴听到您找到解决问题的方法。从 ComboBox 继承还有很多其他含义,不能使其成为您最初问题的正确答案。如果可能,请判断其中一个回答是否解决了原问题,然后标记为正确。
猜你喜欢
  • 2014-06-26
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多