创建新选项卡时,WPF焦点在选项卡控件内容中(WPF Focus In Tab Control Content When New Tab is Created)

编程入门 行业动态 更新时间:2024-10-25 23:38:38
创建新选项卡时,WPF焦点在选项卡控件内容中(WPF Focus In Tab Control Content When New Tab is Created)

我在SO上做了很多搜索并围绕这个问题谷歌,但似乎无法找到任何其他尝试。

我有一个包含选项卡控件的MainView(窗口)。 选项卡控件绑定到ChildViews的ObservableCollection(用户控件)。 MainView的ViewModel有一个方法,允许添加到ChildViews的集合,然后创建一个新的选项卡。 创建新选项卡后,它将成为活动选项卡,这样可以正常工作。 MainView上的此方法是从另一个ViewModel(OtherViewModel)调用的。

我想要做的是在创建新选项卡时将键盘焦点设置到选项卡上的第一个控件(来自WPFToolkit *的AutoCompleteBox)。 我还需要以相同的方式设置焦点,但不创建新选项卡(因此将焦点设置在当前活动的选项卡上)。

(*请注意,AutoCompleteBox似乎存在一些焦点问题 - 即使它确实具有焦点,您需要向其发送一个MoveNext()以将光标移动到其窗口中。我已经解决了这个问题)。

所以这就是问题所在。 当我不创建新选项卡时,聚焦工作,但是当我创建新选项卡时,它不起作用。 两个函数都使用相同的方法来设置焦点,但创建逻辑首先调用创建新选项卡并将其设置为活动的方法。 设置焦点的代码(在ChildView的Codebehind中):

IInputElement element1 = Keyboard.Focus(autoCompleteBox); //plus code to deal with AutoCompleteBox as noted.

在任何一种情况下,Keyboard.FocusedElement都以MainView开头。 在创建之后,调用Keyboard.Focus似乎什么都不做(聚焦元素仍然是MainView)。 在不创建选项卡的情况下调用此选项可将键盘焦点设置为autoCompleteBox。

有任何想法吗?

更新:

班德的建议半成品。

所以现在在这两种情况下,聚焦元素都是正确的AutoCompleteBox。 然后我做的是MoveNext(),它将焦点设置为TextBox。 我一直认为这个文本框是AutoCompleteBox的内部,因为当发生这种情况时焦点在屏幕上正确设置。 现在我不太确定。 这仍然是我在不执行创建时遇到此代码时看到的行为。 创建后,MoveNext()将焦点设置为MainView中的元素。

问题仍然必须与Bender的答案相一致,其中控件的状态不同,具体取决于是否创建了新选项卡。 还有其他想法吗?

最后更新

如上所述,majocha的建议奏效了。

我想更新这个,以防任何人遇到与AutoCompleteBox相同的问题。 似乎设置焦点不会在UI中激活它 - 您需要在其上执行MoveNext以将焦点向前移动一次到控件的内部文本框。 这是基于我的调试经验,可能不是100%科学。 如果我有时间,我将尝试创建一个小的repro项目并将其提交给WPFToolkit团队。

I've done a lot of searching on SO and google around this problem, but can't seem to find anything else to try.

I have a MainView (window) that contains a tab control. The tab control binds to an ObservableCollection of ChildViews (user controls). The MainView's ViewModel has a method that allows adding to the collection of ChildViews, which then creates a new tab. When a new tab is created, it becomes the active tab, and this works fine. This method on the MainView is called from another ViewModel (OtherViewModel).

What I am trying to do is set the keyboard focus to the first control on the tab (an AutoCompleteBox from WPFToolkit*) when a new tab is created. I also need to set the focus the same way, but WITHOUT creating a new tab (so set the focus on the currently active tab).

(*Note that there seem to be some focus problems with the AutoCompleteBox--even if it does have focus you need to send a MoveNext() to it to get the cursor in its window. I have worked around this already).

So here's the problem. The focusing works when I don't create a new tab, but it doesn't work when I do create a new tab. Both functions use the same method to set focus, but the create logic first calls the method that creates a new tab and sets it to active. Code that sets the focus (in the ChildView's Codebehind):

IInputElement element1 = Keyboard.Focus(autoCompleteBox); //plus code to deal with AutoCompleteBox as noted.

In either case, the Keyboard.FocusedElement starts out as the MainView. After a create, calling Keyboard.Focus seems to do nothing (focused element is still the MainView). Calling this without creating a tab correctly sets the keyboard focus to autoCompleteBox.

Any ideas?

Update:

Bender's suggestion half-worked.

So now in both cases, the focused element is correctly the AutoCompleteBox. What I then do is MoveNext(), which sets the focus to a TextBox. I have been assuming that this Textbox is internal to the AutoCompleteBox, as the focus was correctly set on screen when this happened. Now I'm not so sure. This is still the behavior I see when this code gets hit when NOT doing a create. After a create, MoveNext() sets the focus to an element back in my MainView.

The problem must still be along the lines of Bender's answer, where the state of the controls is not the same depending on whether a new tab was created or not. Any other thoughts?

Final Update

As noted, majocha's suggestion worked.

I wanted to update this in case anyone happened upon this same problem with the AutoCompleteBox. It appears that setting focus does not activate it in the UI--you need to do a MoveNext on it to move focus forward once to the control's internal Textbox. This is based on my debugging experience, which may not be 100% scientific. If I have time, I will attempt to create a small repro project and submit it to the WPFToolkit team.

最满意答案

您可以尝试延迟焦点更改

Dispatcher.BeginInvoke(MyChangeFocusAction, DispatcherPriority.ContextIdle);

布局和属性更新完成后,它将排队。 我不认为这是最好的做法,但它对我有用。

You can try defering the focus change with

Dispatcher.BeginInvoke(MyChangeFocusAction, DispatcherPriority.ContextIdle);

It will get queued after layout and properties updates are done. I don't think it's best practice, but it works for me.

更多推荐

本文发布于:2023-08-03 00:07:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1382501.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:选项卡   控件   焦点   内容   Content

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!