【问题标题】:Programmatic focussing of parent Window from a Popup从弹出窗口以编程方式聚焦父窗口
【发布时间】:2013-01-17 19:41:15
【问题描述】:

我目前遇到了 WPF 弹出窗口的问题,其中对所述弹出窗口的操作希望将焦点返回到应用程序的主窗口。

通常,当您单击窗口上的某个位置时,弹出窗口会关闭,这是所需的行为。但是,我发现没有任何编程方式可以以几乎相同的方式将焦点从弹出窗口内的操作带回窗口

以下代码概述了问题:

Xaml:

<Window x:Class="PopupFocusEtc.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" x:Name="_wdw">
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition /><ColumnDefinition />
      </Grid.ColumnDefinitions>
        <TextBox x:Name="_txt" Text="Test" 
                 Grid.ColumnSpan="2" />
        <Button Grid.Row="1" x:Name="_btnOpen" 
                Click="OpenPopup" 
                Content="Open Popup" Grid.ColumnSpan="2" />
        <Popup x:Name="_popup" 
               Placement="Bottom" 
               HorizontalOffset="10"
               PlacementTarget="{Binding ElementName=_btnOpen}"
               StaysOpen="False">
          <Button Click="SwitchFocus" 
                  MinHeight="100" MinWidth="100" 
                  Margin="5"
                  Content="Focus" />
        </Popup>
        <Rectangle Grid.Column="1" Grid.Row="2" 
                   Fill="DarkOliveGreen">
          <Rectangle.Style>
            <Style TargetType="Rectangle">
              <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="Cursor" Value="Hand" />
                </Trigger>
              </Style.Triggers>
            </Style>
          </Rectangle.Style>
        </Rectangle>
    </Grid>
</Window>

代码隐藏:

using System.Windows;
using System.Windows.Input;

namespace PopupFocusEtc
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenPopup(object sender, RoutedEventArgs e)
        {
            _popup.IsOpen = true;
        }

        private void SwitchFocus(object sender, RoutedEventArgs e)
        {
            _txt.Focus();
            Keyboard.Focus(_txt);
            _txt.SelectAll();
            _wdw.Activate();
        }
    }
}

当我单击弹出窗口中的按钮时,文本框正确聚焦,我什至可以输入文本,但弹出窗口保持打开状态。此外,请注意将光标切换为手的矩形上的 MouseOver 效果。即使窗口有焦点,效果不起作用

只有当我点击进入窗口时,弹出框才会消失,效果会再次起作用,等等。

我的问题是:鉴于这种情况,我如何让主窗口再次激活,就像我点击它一样?

更新

我知道在给定的示例中,我可以简单地关闭代码隐藏中的弹出窗口。这是一个简化的示例 - 在另一个应用程序中,从 Popup UI 中开始的操作不知道它存在于 Popup 上,并且主窗口上发生的任何事情都不知道关于弹出窗口

因此,在 UI 中引入更多耦合之前,我想知道当您单击窗口时运行的机制是否可以通过某种方式以编程方式触发...

【问题讨论】:

    标签: .net wpf xaml focus


    【解决方案1】:

    我不清楚您上面提供的示例是否模仿了所需的方法,但如果您只是添加以下行:

     _popup.IsOpen = false;
    

    SwitchFocus 方法中(我会把它放在_wdw.Activate() 之前,但它也可以在之后工作),然后当您单击按钮时弹出窗口关闭,TextBox 获得焦点。

    这就是你要找的吗?

    【讨论】:

    • 是的,我应该将其添加到问题中,我会的。在发生这种情况的实际应用程序中,将焦点放在主窗口上的部分实际上对来自弹出窗口的动作一无所知 - 所以,在我求助于将弹出窗口实例耦合到触发聚焦的动作之前,我是搜索如何“正确”激活窗口,就像点击它一样。
    • 那么您是说您希望弹出窗口不知道文本框吗?还是父窗口?
    • 关键是有一种机制可以关闭弹出窗口并激活窗口,您只需单击窗口即可看到该机制。如果我可以利用这一点,我就不需要知道任何关于弹出窗口的信息。
    • 我可能是错的,但我认为你所指的机制只是弹出窗口中的逻辑,当它失去焦点时会自行关闭。有一个弹出设置可让您将其关闭(因此即使失去焦点,它也会保持打开状态)。我认为它与接收焦点的窗口/组件没有任何关系。如果您还没有,我建议您查看 WPF 焦点概述,看看其中一个焦点事件是否可以满足您的需求:msdn.microsoft.com/en-us/library/aa969768.aspx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多