WPF弹出位置问题

时间:2013-12-03 22:32:54

标签: wpf xaml

我遇到了一个奇怪的WPF弹出窗口放置问题。

我已经定义了这个XAML:

<Window x:Class="PositionBug.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="300" Width="525">
<Grid>
    <TextBlock Name="Textblock1" Height="60" Width="300" Background="LightGray" HorizontalAlignment="Center"
               VerticalAlignment="Bottom">The PlacementTarget</TextBlock>
    <Popup Name="Popup1" PlacementTarget="{Binding ElementName=Textblock1}" Placement="Top" Width="120" Margin="198,0,199,0" IsOpen="True">
        <TextBlock Background="LightBlue" FontSize="18">This is a Popup</TextBlock>
    </Popup>
</Grid>

在大多数计算机上,这是结果,如预期的那样: correct

但是,在一个特定计算机型号的多个单元上,结果如下所示: incorrect

有没有办法强制将Placement置于Top和Left?

5 个答案:

答案 0 :(得分:2)

菜单和弹出窗口的左右对齐似乎由这个特殊的注册表项控制:

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows

REG_SZ: MenuDropAlignment

Value: 0 表示向右

Value: 1 表示向左

不知何故,我的系统从右到左切换了菜单和弹出窗口对齐方式。我检查了这个注册表项,果然值是 1,所以我把它改回 0,现在我的 WPF 弹出对齐按预期工作。

答案 1 :(得分:0)

我能够在惠普笔记本电脑上修复此问题。原来它有一个触摸屏,它使用左/右手&#34;选择下拉菜单和弹出窗口是否与目标控件左右对齐(使用顶部或底部对齐时)。

要修复此问题,请转到“控制面板”,搜索(右上角)并键入 Tablet PC设置。在该对话框上(在某些Windows版本的 General 选项卡下,以及其他PC上的 Other 选项卡),您将看到右手和左手操作的选项

正确合理的弹出窗口更好&#34;如果菜单和弹出窗口显示在被触摸点的左侧,则右手不会遮挡组件。当然,如果您主要使用鼠标,那么它看起来很奇怪并让我们的开发人员感到困惑!

答案 2 :(得分:0)

我在我正在处理的应用程序中遇到与弹出窗口相同的问题。我不能指望客户更改其平板电脑上的设置,因此我使用此代码来修复每个人的弹出窗口定位:

var simplePlacement = new CustomPopupPlacement(new Point(0, 0), PopupPrimaryAxis.None);
popup.Placement = PlacementMode.Custom;
popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback((popupSize, targetSize, offset) => new [] { simplePlacement });

答案 3 :(得分:0)

更新:如果您想将其应用于整个窗口,这是一个更好的解决方案:WPF Handedness with Popups

ORIGINAL:

我意识到这是一个老线程,但我只是碰到了这个。有了这个:

<!--POPUP PLACEMENT HACK-->
<Rectangle 
  x:Name="PART_PopPlacer" 
  Fill="Red"
  Width="0" 
  Height="0"
  HorizontalAlignment="Left"
  VerticalAlignment="Bottom"
  Focusable="False"
  Visibility="Hidden"
  IsHitTestVisible="False"
/>

<Popup 
    Name="Popup"
    Placement="Left" 
    PlacementTarget="{Binding ElementName=PART_PopPlacer}"
    ...

我明白了:

enter image description here

我不想依赖用户设置,我想避免代码背后和数学。所以我只是做了这个DIRTY hack但在角落里使用了一个空心矩形。好的是,当屏幕的不同边缘仍然有效时,所有用于移动弹出窗口的内置逻辑:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
    <!-- COMBO BOX STYLE AND TEMPLATE -->
    <Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
        <Setter Property="MinWidth" Value="120"/>
        <Setter Property="MinHeight" Value="20"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid>

                        <ToggleButton 
                            Background="White"
                            Focusable="false"
                            IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                            ClickMode="Press"
                          />

                        <ContentPresenter
                            Name="ContentSite"
                            IsHitTestVisible="False" 
                            Content="{TemplateBinding SelectionBoxItem}"
                            Margin="2"
                          />

                        <!--POPUP PLACEMENT HACK-->
                        <Rectangle 
                          x:Name="PART_PopPlacer" 
                          Fill="Red"
                          Width="0" 
                          Height="0"
                          HorizontalAlignment="Left"
                          VerticalAlignment="Bottom"
                          Focusable="False"
                          Visibility="Hidden"
                          IsHitTestVisible="False"
                      />

                        <Popup 
                            Name="Popup"
                            Placement="Left" 
                            PlacementTarget="{Binding ElementName=PART_PopPlacer}"
                            VerticalOffset="6"
                            IsOpen="{TemplateBinding IsDropDownOpen}"
                            AllowsTransparency="True" 
                            Focusable="False"
                            PopupAnimation="Slide">
                            <Grid 
                              Name="DropDown"
                              SnapsToDevicePixels="True">
                                <Border 
                                    Name="DropDownBorder"
                                    Background="LightYellow"
                                    BorderThickness="1"
                                    BorderBrush="Black"/>
                                <ScrollViewer Margin="2" SnapsToDevicePixels="True">
                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                </ScrollViewer>
                            </Grid>
                        </Popup>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Page.Resources>

<StackPanel>
    <ComboBox Height="20" Width="50" SelectedIndex="0" Margin="20">
        <ComboBoxItem Content="Very Very Very Very Long Text" />
        <ComboBoxItem Content="Text" />
        <ComboBoxItem Content="Text" />
        <ComboBoxItem Content="Text" />
        <ComboBoxItem Content="Text" />
    </ComboBox>
</StackPanel>

</Page>

这给了这个:

enter image description here

完整代码(应该将矩形放在xaml的顶部,以便它可以被级联元素覆盖):

{{1}}

答案 4 :(得分:0)

转到“系统设置” -“硬件和声音” -“平板电脑设置” -《二手手》 -选择“惯用右手”(PopUps,DropDowns左对齐)        或“惯用左手”(PopUps,DropDowns右对齐)