Tommy Mikalsen
Tommy Mikalsen

Reputation: 56

WPF popup location issue

I am experiencing a strange WPF popup placement issue.

I have defined this 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>

On most computers this is the result, as expected: correct

However, on multiple units of one specific computer model, the result is presented like this: incorrect

Is there any way to force Placement to both Top AND Left?

Upvotes: 4

Views: 5414

Answers (5)

tia.misu
tia.misu

Reputation: 216

The left and right alignment of menus and popups appears to be controlled by this special registry key:

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

REG_SZ: MenuDropAlignment

Value: 0 means to the right

Value: 1 means to the left

Somehow my system switched the menu and popup alignment from right to left. I checked this registry key and sure enough the value was 1 so I changed it back to 0 and now my WPF Popup alignments are working as expected.

Upvotes: 8

Nogari Sakuto
Nogari Sakuto

Reputation: 1

Go to "system settings" - "hardware & sound" - "tablet pc-settings" - "to be used writing hand" - select "right-handed" (PopUps, DropDowns align left) or "left-handed" (PopUps, DropDowns align right)

Upvotes: 0

Ernie S
Ernie S

Reputation: 14250

UPDATE: Here is a better solution if you want to make it apply to the entire Window: WPF Handedness with Popups

ORIGINAL:

I realize this is an old thread but I just ran across this. With this:

<Popup 
    Name="Popup"
    Placement="Bottom" 
    PlacementTarget="{Binding ElementName=ToggleButton}"
    ...

I get this:

enter image description here

I didnt want to rely on the user settings and I wanted to avoid code behind and math. So I just did this DIRTY hack but using a hollow rectangle in the corner. Good thing is all of the built-in logic for shifting the popup when at different edges of the screen all still work:

<!--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}"
    ...

Which gave this:

enter image description here

The full code (should probably put the rectangle at the top of the xaml so it can be covered by the cascading elements):

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

Upvotes: 4

Mike Prosser
Mike Prosser

Reputation: 29

I had the same issue with popups in an application I'm working on. I can't expect customers to change the settings on their Tablet PCs, so I used this code to fix the popup positioning for everyone:

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

Upvotes: 0

Larry S
Larry S

Reputation: 457

I was able to fix this on my HP laptop. Turns out since it has a touch screen, it uses a left/right "handedness" to choose whether drop-down menus and popups are left- or right-aligned with the target control (when using Top or Bottom alignment).

To fix, go to Control Panel, search (upper right corner) and type Tablet PC Settings. On that dialog (under General tab on some versions of Windows, and the Other tab on other PCs) you'll see options for right- and left-handed operation.

The right-justified popups are "better" if the menus and popups show to the left of the point being touched, so the right hand doesn't obscure the component. Of course if you primarily use a mouse, then it just looks weird and confuses us developers!

Upvotes: 2

Related Questions