WPF检测Popup的最终位置

时间:2014-06-23 22:52:02

标签: wpf c#-4.0 popup placement

是否可以检测弹出窗口的最终位置?我有一个自定义弹出窗口呈现在指定的UI元素下面,我希望它相对于其位置绘制一个边框到指定的UI控件。默认情况下行为正常,因此弹出窗口会在控件下方绘制。
但是,如果遇到屏幕边缘弹出行为,则会在不同位置绘制弹出窗口。我的问题是在那里检测弹出窗口的最终位置是什么,然后绘制相应于其新位置的边框。
或者如果弹出窗口是在不同于默认位置的位置绘制的话,这是否需要手动处理放置。

修改
下面是Git Extensions的图片,因为你看到没有任何线条与下拉列表的其余部分分开“dev”。现在我已经能够愉快地复制这种行为了。然而弹出窗口有这个简洁的功能,如果遇到一个屏幕边缘,弹出窗口将移动accordingly,这不是我的问题,因为当弹出窗口移位或渲染在另一个点我需要拿起这个班次和适当地绘制弹出框架边框。即如果弹出的选择选项被绘制在开发按钮上方,弹出窗口的顶部将有一个完整的行,底部将有适当的间隙(抱歉没有图片示例)。当我有机会时,我会画一个例子。

我希望编辑有帮助:)

enter image description here

1 个答案:

答案 0 :(得分: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>

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

结果

popup

您可以使用可重复使用的样式包装边框和/或阴影

修改

我尝试与您的要求相匹配,同时为同一个

创建了一个可重复使用的模板
<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>

结果

result