在 WPF 中以编程方式选择 tabItem

发布于 2024-07-22 07:01:19 字数 298 浏览 12 评论 0原文

我在 TabControl 中有不同的 tabItems 每个 tabItem 都有一些输入字段。

我以编程方式在 tabItems 之间移动(就像从第一个移动到下一个的向导)

我在“下一步”按钮中使用此代码

tabItem2.isSelected = true;

我的问题是,当我通过单击选项卡项目在选项卡项目之间移动时,焦点(键盘焦点)将移动到第一个文本框输入。

但以编程方式使用前面的代码,焦点不会移动到 tabItem 内的第一个输入文本框项。

任何想法?

I have different tabItems in a TabControl
and each tabItem has some input fields.

I am moving between the tabItems programmatically (like a wizard to move from the first to the next)

I am using this code inside the "Next" button

tabItem2.isSelected = true;

my problem that when I move between the tabItems by clicking on them, the focus (keyboard focus) will move to the first textbox input.

But programmatically with the previous code, the focus won't move to the first input textbox item inside the tabItem.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风夜微凉 2024-07-29 07:01:19

如果您强制使用 IsSelected 属性,我还会为第一个 TextBox 指定一个名称,并在设置所选选项卡后设置焦点。

如果您动态构建 UI,这将不起作用,但您可以创建一个实用程序方法,该方法在逻辑树(或视觉树,如果您使用演示者/视图模型)中搜索第一个输入控件,然后设定焦点。

If you're forcing the IsSelected property, I'd also give the first TextBox a name and set the focus after you set the selected tab.

If you're building your UI dynamically, this won't work, but you can create a utility method which searches the logical tree (or the visual tree if you're using presenters/view-models) for the first input control and then set the focus.

淡淡の花香 2024-07-29 07:01:19

这些解决方案对我不起作用。 它已经选择了我想要的 TabItem,但无法选择/聚焦所需的 TreeViewItem。 (如果已经选择了 TabItem,它只会聚焦 TVI。)下面的解决方案最终对我有用。

(仅供参考:下面的代码片段是类似于 Microsoft Help Viewer 2.0 的应用程序的一部分。当您单击“同步”按钮时,它首先选择“内容”选项卡(如果尚未选择),然后遍历树视图,直到找到匹配的树然后它会选择/聚焦查看项目。)

干杯

private void OnClick_SyncContents(object sender, RoutedEventArgs e)
{
    // If the help-contents control isn't visible (ie., some other tab is currently selected),
    // then use our common extension method to make it visible within the tab control.  Once
    // it visible, the extension method will call the event handler passed (which is this method)
    if (!this.m_UcHelpFileContents.IsVisible)
    {
      this.m_UcHelpFileContents.
      SelectParentTabItem_WaitForMeToBecomeVisible_ThenCallThisEventHandlerWithNullArguments
      (this.OnClick_SyncContents);
    }
    else 
    {
      // Else the help-contents control is currently visible, thus focus the 
      // matching tree view item
      /* Your code here that focuses the desired tree view item */
    }
}


public static class CommonExtensionMethods
{
  public static void
    SelectParentTabItem_WaitForMeToBecomeVisible_ThenCallThisEventHandlerWithNullArguments
    (this FrameworkElement frameworkElement, RoutedEventHandler eventHandlerToCallWhenVisible)
  {
    // First, define the handler code for when the given framework element becomes visible
    DependencyPropertyChangedEventHandler HANDLER = null;
    HANDLER = (s, e) =>
    {
      // If here, the given framework element is now visible and its tab item currently selected
      // Critical: first and foremost, undo the latch to is-visible changed
      frameworkElement.IsVisibleChanged -= HANDLER;

      // Now invoke the event handler that the caller wanted to invoke once visible
      frameworkElement.Dispatcher.BeginInvoke(eventHandlerToCallWhenVisible, null, null);
    };

    // Use our common extension method to find the framework element's parent tab item
    TabItem parentTabItem = frameworkElement.GetFirstParentOfType<TabItem>();

    if (parentTabItem != null)
    {
      // Assign the handler to the given framework element's is-visible-changed event
      frameworkElement.IsVisibleChanged += HANDLER;

      // Now set the tab item's is-selected property to true (which invokes the above 
      // handler once visible)
      parentTabItem.IsSelected = true;
    }
  }


  public static T GetFirstParentOfType<T>
    (this FrameworkElement frameworkElement) where T : FrameworkElement
  {
    for (FrameworkElement fe = frameworkElement.Parent as FrameworkElement; 
         fe != null; 
         fe = fe.Parent as FrameworkElement)
    {
      if (fe is T)
        return fe as T;
    }

    // If here, no match
    return null;
  }
}

These solutions didn't work for me. It got as far selecting the TabItem I wanted, but it wasn't able to select/focus the desired TreeViewItem. (It would only focus the TVI if the TabItem was already selected.) The solution below finally worked for me.

(FYI: The snippets below are part of app that is similar to Microsoft Help Viewer 2.0. When you click the "Sync" button, it first selects the Contents tab if not already selected, then traverses into tree view until it finds the matching tree view item. Which it then selects/focuses.)

Cheers

private void OnClick_SyncContents(object sender, RoutedEventArgs e)
{
    // If the help-contents control isn't visible (ie., some other tab is currently selected),
    // then use our common extension method to make it visible within the tab control.  Once
    // it visible, the extension method will call the event handler passed (which is this method)
    if (!this.m_UcHelpFileContents.IsVisible)
    {
      this.m_UcHelpFileContents.
      SelectParentTabItem_WaitForMeToBecomeVisible_ThenCallThisEventHandlerWithNullArguments
      (this.OnClick_SyncContents);
    }
    else 
    {
      // Else the help-contents control is currently visible, thus focus the 
      // matching tree view item
      /* Your code here that focuses the desired tree view item */
    }
}


public static class CommonExtensionMethods
{
  public static void
    SelectParentTabItem_WaitForMeToBecomeVisible_ThenCallThisEventHandlerWithNullArguments
    (this FrameworkElement frameworkElement, RoutedEventHandler eventHandlerToCallWhenVisible)
  {
    // First, define the handler code for when the given framework element becomes visible
    DependencyPropertyChangedEventHandler HANDLER = null;
    HANDLER = (s, e) =>
    {
      // If here, the given framework element is now visible and its tab item currently selected
      // Critical: first and foremost, undo the latch to is-visible changed
      frameworkElement.IsVisibleChanged -= HANDLER;

      // Now invoke the event handler that the caller wanted to invoke once visible
      frameworkElement.Dispatcher.BeginInvoke(eventHandlerToCallWhenVisible, null, null);
    };

    // Use our common extension method to find the framework element's parent tab item
    TabItem parentTabItem = frameworkElement.GetFirstParentOfType<TabItem>();

    if (parentTabItem != null)
    {
      // Assign the handler to the given framework element's is-visible-changed event
      frameworkElement.IsVisibleChanged += HANDLER;

      // Now set the tab item's is-selected property to true (which invokes the above 
      // handler once visible)
      parentTabItem.IsSelected = true;
    }
  }


  public static T GetFirstParentOfType<T>
    (this FrameworkElement frameworkElement) where T : FrameworkElement
  {
    for (FrameworkElement fe = frameworkElement.Parent as FrameworkElement; 
         fe != null; 
         fe = fe.Parent as FrameworkElement)
    {
      if (fe is T)
        return fe as T;
    }

    // If here, no match
    return null;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文