是什么使我的WPF弹出窗口与其PlacementTarget的右边缘对齐?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是什么使我的WPF弹出窗口与其PlacementTarget的右边缘对齐?相关的知识,希望对你有一定的参考价值。
我试图理解为什么我的WPF弹出窗口似乎与其PlacementTarget的右边缘对齐:
通常,弹出窗口应与左侧对齐。
这是在一个较大的项目中,我插入了许多代码,样式等。我试图简化并提取示例,并且-令我惊讶的是,如果该示例在其他空白的单独应用程序中运行,则可以正确对齐:] >
我搜索了要排除的代码:
- 代码或资源中的任何地方都没有HorizontalOffset
- 在代码或资源中的任何地方都没有FlowDirection =“ RightToLeft”
我几乎试图从项目中删除所有ResourceDictionaries,但那些项目甚至无法生成或启动的除外。
我还通过探听调查了弹出窗口,它具有正确的放置目标,没有偏移和正确的放置。
我在这里迷路了。有什么理论可能导致这种情况?
这里是示例代码(由于原始代码将其作为用户控件,因此看起来可能有点复杂:]
<Window x:Class="PopupIssue.client.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="Window1" Height="450" Width="800"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="80" /> <ColumnDefinition Width="3" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <StackPanel Orientation="Vertical"> <Border Background="Blue" Height="40"/> <Button x:Name="DropdownParent" Click="Button_OnClick" Focusable="True" KeyboardNavigation.AcceptsReturn="False" > <Button.Template> <ControlTemplate TargetType="Button"> <StackPanel> <Border Margin="2" Background="AliceBlue"> <Grid x:Name="DropdownMain" > <!-- Background="#FFE3E8EA">--> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="20" MaxWidth="20" /> </Grid.ColumnDefinitions> <Border Grid.Column="0" Grid.ColumnSpan="2"> <TextBlock Text="" /> </Border> <Border Grid.Column="1" Margin="2" Padding="5" Background="LightSalmon"> <Path x:Name="Arrow" Fill="Gray" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z" /> </Border> </Grid> </Border> <Popup Placement="Bottom" IsOpen="{Binding ShowPopup}" PlacementTarget="{Binding ElementName=DropdownParent}" PopupAnimation="Fade" StaysOpen="True" MinWidth="{Binding ActualWidth, ElementName=DropdownParent}" Closed="Popup_OnClosed" Opened="Popup_OnOpened" KeyDown="Popup_OnKeyDown"> <Border Background="White" Padding="5,2,5,2" BorderBrush="Red" BorderThickness="1"> <StackPanel> <StackPanel.Resources> <Style TargetType="{x:Type RadioButton}"> <Setter Property="Margin" Value="0,10,0,0"/> </Style> </StackPanel.Resources> <RadioButton Content="Lorem Ipsum Dolor Ahmed Quid Prio" GroupName="rbGroup" ></RadioButton> <RadioButton Content="Lorem Ipsum Dolor Ahmed Quid Prio" GroupName="rbGroup" ></RadioButton> <RadioButton Content="Lorem Ipsum Dolor Ahmed Quid Prio" GroupName="rbGroup" ></RadioButton> <RadioButton Content="Lorem Ipsum Dolor Ahmed Quid Prio" GroupName="rbGroup" ></RadioButton> <RadioButton Content="Lorem Ipsum Dolor Ahmed Quid Prio" GroupName="rbGroup" ></RadioButton> </StackPanel> </Border> </Popup> </StackPanel> </ControlTemplate> </Button.Template> </Button> <Border Background="Blue" Height="40"/> </StackPanel> <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> <Border Background="Beige" Grid.Column="2" /> </Grid> </Window>
using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Threading; namespace PopupIssue.client { /// <summary> /// Interaktionslogik für Window1.xaml /// </summary> public partial class Window1 : Window, INotifyPropertyChanged { public Window1() { this.DataContext = this; InitializeComponent(); } private bool showPopup; public bool ShowPopup { get => showPopup; set { showPopup = value; NotifyPropertyChanged("ShowPopup"); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } private DateTime lastClosed = DateTime.MinValue; private void Popup_OnClosed(object sender, EventArgs e) { lastClosed = DateTime.Now; var tmp = OnPopupClosed; if (tmp != null) tmp(this, new EventArgs()); Action a = () => this.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); Dispatcher.BeginInvoke(DispatcherPriority.Background, a); } public event EventHandler<EventArgs> OnPopupClosed; public event EventHandler<EventArgs> OnPopupOpened; private void Button_OnClick(object sender, RoutedEventArgs e) { // When button is clicked while the popup is already open, then the popup is closed automatically by the system before this event handler. // So when this method is executed, the popup is always closed. // However if the user clicked the button while the popup was open, then he expects the popup to close (which the system does automatically) and not to immediately re-open. // The only viable way is to check if the popup closed immediately (<200 ms) before the click and not open the popup then var millisSinceClose = (DateTime.Now - lastClosed).TotalMilliseconds; if (millisSinceClose > 200) ShowPopup = true; } private void Popup_OnOpened(object sender, EventArgs e) { var f = Content as FrameworkElement; if (f != null) { Action a = () => f.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); Dispatcher.BeginInvoke(DispatcherPriority.Background, a); var tmp = OnPopupOpened; if (tmp != null) tmp(this, new EventArgs()); } } private void Popup_OnKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) { ((Popup)sender).IsOpen = false; e.Handled = true; } } } }
我试图理解为什么我的WPF弹出窗口看起来与其PlacementTarget的右边缘对齐:通常,期望弹出窗口与左侧对齐。这是在一个较大的项目中,我...
答案
我相信我找到了不同的行为的原因:Windows似乎是针对触摸的,如何在系统范围内对齐弹出窗口(主要是菜单)的设置。您可以将其设置为左手或右手(搜索MenuDropAlignment)。
以上是关于是什么使我的WPF弹出窗口与其PlacementTarget的右边缘对齐?的主要内容,如果未能解决你的问题,请参考以下文章