【问题标题】:WPF Detecting final placement of PopupWPF检测弹出窗口的最终位置
【发布时间】:2014-06-24 14:33:54
【问题描述】:

是否可以检测弹出窗口的最终位置?我有一个在指定 UI 元素下方呈现的自定义弹出窗口,我希望它相对于指定 UI 控件的位置绘制边框。默认情况下,该行为是正常的,因此弹出窗口绘制在控件下方。
但是,根据弹出窗口行为,如果遇到屏幕边缘,弹出窗口将绘制在不同的位置。我的问题是要检测弹出窗口的最终位置是否是,然后根据其新位置绘制边框。
或者这是否需要手动过程才能确定弹出窗口是否绘制在与其默认位置不同的位置.

编辑
下面是来自 Git Extensions 的图片,因为您看到没有将“dev”与下拉列表的其余部分分开的行。现在我已经能够愉快地复制这种行为了。但是弹出窗口有这个简洁的功能,如果遇到屏幕边缘,弹出窗口将移动accordingly,这不是我的问题,因为当弹出窗口移动或在另一个点呈现时,我需要拿起这个移动并绘制弹出窗口的边界适当。也就是说,如果在开发按钮上方绘制选择选项弹出窗口,则弹出窗口的顶部将有一条完整的线,底部将有适当的间隙(抱歉没有图片示例)。有机会我会举个例子。

我希望编辑有帮助:)

【问题讨论】:

  • 我确信在Popup 中使用一个事件并检查Placement 属性会得到你想要的。
  • 我尝试了 Opened 事件,但即使呈现在控件上方,位置仍设置为底部。
  • 你能分享一下你想要实现的目标吗?
  • 我添加了更多细节,希望对您有所帮助:)

标签: wpf c#-4.0 popup placement


【解决方案1】:

似乎您正在尝试在弹出窗口周围创建边框

这是一个示例

<Grid>
    <ToggleButton Content="open popup"
                  x:Name="toggle"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center" />
    <Popup PlacementTarget="{Binding ElementName=toggle}"
           IsOpen="{Binding IsChecked,ElementName=toggle}"
           AllowsTransparency="True">
        <Border Background="White"
                CornerRadius="4"
                BorderBrush="Black"
                BorderThickness="1"
                Padding="5"
                Margin="0,0,10,10">
            <StackPanel>
                <Button Content="somebutton" />
                <RadioButton Content="a radiobutton" />
                <CheckBox Content="a checkbox" />
            </StackPanel>
            <Border.Effect>
                <DropShadowEffect Opacity=".25" />
            </Border.Effect>
        </Border>
    </Popup>
</Grid>

使用这种方法,即使弹出窗口的某些部分超出应用边界,您也可以绘制边框或阴影

结果

您可以将边框和/或阴影包裹在可重复使用的样式中以实现重复使用

编辑

我尝试满足您的要求,也为相同创建了一个可重复使用的模板

<Grid RenderOptions.EdgeMode="Aliased">
    <Grid.Resources>
        <ControlTemplate TargetType="HeaderedContentControl"
                         x:Key="PopupButton">
            <Grid>
                <ToggleButton Content="{TemplateBinding Header}"
                              x:Name="toggle"
                              HorizontalAlignment="Center"
                              VerticalAlignment="Center">
                    <ToggleButton.Template>
                        <ControlTemplate TargetType="ToggleButton">
                            <Border BorderBrush="Gray"
                                    Background="White"
                                    BorderThickness="1"
                                    Padding="4"
                                    x:Name="border">
                                <StackPanel Orientation="Horizontal">
                                    <ContentPresenter />
                                    <TextBlock Text="▼"
                                               Margin="4,0,0,0"
                                               FontSize="8"
                                               VerticalAlignment="Center" />
                                </StackPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsChecked"
                                         Value="True">
                                    <Setter Property="BorderThickness"
                                            TargetName="border"
                                            Value="1,1,1,0" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </ToggleButton.Template>
                </ToggleButton>
                <Popup PlacementTarget="{Binding ElementName=toggle}"
                       IsOpen="{Binding IsChecked,ElementName=toggle}"
                       AllowsTransparency="True">
                    <Grid>
                        <Border Background="White"
                                BorderBrush="Gray"
                                BorderThickness="1"
                                Padding="5"
                                Margin="0,0,5,5">
                            <ContentPresenter />
                            <Border.Effect>
                                <DropShadowEffect Opacity=".25" />
                            </Border.Effect>
                        </Border>
                        <Rectangle Fill="White"
                                   Stroke="Transparent"
                                   StrokeThickness="1"
                                   Width="{Binding ActualWidth,ElementName=toggle}"
                                   Height="3"
                                   Margin=".5,-1,0,0"
                                   HorizontalAlignment="Left"
                                   VerticalAlignment="Top" />
                    </Grid>
                </Popup>
            </Grid>
        </ControlTemplate>
    </Grid.Resources>
    <HeaderedContentControl Header="dev"
                            Template="{StaticResource PopupButton}">
        <StackPanel>
            <Button Content="somebutton" />
            <RadioButton Content="a radiobutton" />
            <CheckBox Content="a checkbox" />
        </StackPanel>
    </HeaderedContentControl>
</Grid>

您可以在资源中定义模板,在应用中为多个项目定义模板

例如

    <HeaderedContentControl Header="header"
                            Template="{StaticResource PopupButton}">
        <!--popup content here-->
    </HeaderedContentControl>

结果

【讨论】:

  • 啊,是的,边界是想法,但问题是确保弹出窗口和按钮之间没有间隙线。看看编辑希望它有助于解释更多:)
  • 看起来不错。但是,如果您移动窗口,弹出窗口不会移动。这个挑战的想法?
  • @Christoph,这是弹出窗口的预期行为。最简单的方法是在窗口收到点击等后关闭弹出窗口。另一个选择是将弹出窗口位置与主窗口同步。请随时为此创建一个新问题。
猜你喜欢
  • 2017-09-06
  • 2011-04-27
  • 2010-10-21
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多