windows 为什么我的Wpf弹出窗口被放置在错误的一侧?

z4bn682m  于 2023-05-19  发布在  Windows
关注(0)|答案(1)|浏览(193)

我做了一个Wpf代码,它从C#代码创建弹出窗口。我希望将弹出窗口放置在UserControl的右侧,但这只发生在我设置popup.Placement = PlacementMode.Left;时。

注意:

  • MainWindow有一个名为MyGridGrid
  • 一个名为MyUserControlUserControl将嵌入到MyGrid中。

这是UserControl xaml代码:

<Grid Background="AliceBlue" Width="270" Height="100">
    <Button Width="50" 
            Height="20" 
            HorizontalAlignment="Right" 
            VerticalAlignment="Center"
            Click="TestButton_Click"/>
</Grid>

C#代码如下
1.我的想法是在MainWindow中创建UserControl(MyUserControl)时将参数(MainWindow中的MyGrid)传递给它。

public partial class MyUserControl : UserControl
 {
     UIElement Parent = null;
     public delegate void TestButtonMouseClick(UIElement target);
     public static event TestButtonMouseClick ETestButtonMouseClick;

     public MyUserControl(UIElement parent)
     {
         InitializeComponent();
         this.Parent = parent;
     }

     private void TestButton_Click(object sender, RoutedEventArgs e)
     {
         ETestButtonMouseClick?.Invoke(Parent);
     }
 }

对于主窗口,其xaml代码如下所示。
1.这个MyGrid可以位于MainWindow中的任何位置,我将其用作UserControl的容器。
1.当单击按钮时,代理将传递参数(MyGrid)作为Popup的PlacementTarget的目标。
最后,当我设置popup.Placement = PlacementMode.Left;然后如上图所示:弹出窗口出现在UserControl的右侧。如果我设置了popup.Placement = PlacementMode.Right,那么弹出窗口将出现在UserControl的左侧。为什么?
可行的演示项目可以在这里找到:https://github.com/tomxue/MyPopupIssue.git

<Grid>
    <Grid x:Name="MyGrid" 
          HorizontalAlignment="Center" 
          VerticalAlignment="Center" 
          Width="270"
          Height="100"/>
</Grid>

它的C#代码是:

public MainWindow()
{
    InitializeComponent();
    MyUserControl userControl = new MyUserControl(MyGrid);
    MyGrid.Children.Add(userControl);
    MyUserControl.ETestButtonMouseClick += MyUserControl_ETestButtonMouseClick;
}

private void MyUserControl_ETestButtonMouseClick(UIElement target)
{
    Application.Current.Dispatcher.InvokeAsync(new Action(() =>
    {
        Popup popup = new Popup();
        popup.AllowsTransparency = true;
        popup.PlacementTarget = target;
        popup.HorizontalOffset = 10;
        popup.VerticalOffset = 41;
        popup.Placement = PlacementMode.Left;
        popup.StaysOpen = false;

        TextBlock myTextBlock = new TextBlock();
        myTextBlock.HorizontalAlignment = HorizontalAlignment.Center;
        myTextBlock.VerticalAlignment = VerticalAlignment.Center;
        myTextBlock.Width = 166;
        myTextBlock.Height = 170;
        myTextBlock.Text = "Just a test.";
        myTextBlock.FontSize = 22;
        myTextBlock.Foreground = new SolidColorBrush(Colors.Red);
        myTextBlock.Background = new SolidColorBrush(Colors.Yellow);
        popup.Child = myTextBlock;
        popup.IsOpen = true;
    }));
}

**更多:**我测试yeaterday晚上在家里。刚才我在办公室又做了一次测试。下面的图片再次显示了我的问题。我使用Visual Studio 2022社区版本。

ni65a41a

ni65a41a1#

这是触摸屏支持的问题。你肯定有触摸屏支持和“鲁弗爵士”没有。因此,在触摸设备上,左和右被交换(右/左撇子支持可能也会影响行为)。
解决方法:

var isTouchDev = Tablet.TabletDevices.OfType<TabletDevice>().Any(dev => dev.Type == TabletDeviceType.Touch);

var popup = new Popup();
popup.AllowsTransparency = true;

popup.Placement = isTouchDev ? PlacementMode.Right : PlacementMode.Left;

popup.PlacementTarget = target;
popup.VerticalOffset = 41;

popup.HorizontalOffset = isTouchDev ? -10 : 10;

相关问题