[英]WPF Initial focus for each TabItem
Okay, I know this title looks like it has answers all around SO, but none of the answers found here worked for me.好的,我知道这个标题看起来像是在 SO 周围都有答案,但是这里找到的答案都没有对我有用。 So, here goes.
所以,这就开始了。
I have this layout:我有这个布局:
<Window>
<Grid>
<DockPanel>
<TabControl>
<TabItem>
<Page x:Name="p">
<Grid x:Name="g2">
<TabControl x:Name="tc">
<TabItem x:Name="ti1">
<StackPanel x:Name="sp">
<C:TextBox x:Name="txt"/>
</StackPanel>
</TabItem>
<TabItem x:Name="ti2">
<C:DataGrid x:Name="dg"/>
</TabItem>
</TabControl>
</Grid>
</Page>
</TabItem>
</TabControl>
</DockPanel>
</Grid>
</Window>
Now, my goal is to put focus on txt
TextBox
when ti1
TabItem
gets selected and on dg
DataGrid
when ti2
TabItem
gets selected.现在,我的目标是把重点放在
txt
TextBox
时ti1
TabItem
被选中,并在dg
DataGrid
当ti2
TabItem
被选中。 Also, I would really love to set this in XAML
.另外,我真的很想在
XAML
设置它。
Note: I can only use controls that are named here, so up until Page
control.注意:我只能使用此处命名的控件,直到
Page
控件为止。
What have I tried so far:到目前为止我尝试了什么:
FocusManager.FocusedElement="{Binding ElementName=txt}"
on all of the parent controls in the parent tree of the txt
Control
(up until Page
).txt
Control
的父树中的所有父控件上设置FocusManager.FocusedElement="{Binding ElementName=txt}"
(直到Page
)。FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
on the txt
and dg
controls.txt
和dg
控件上设置FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
。 setting focus in code through TabControl
's SelectionChanged
event:通过
TabControl
的SelectionChanged
事件在代码中设置焦点:
TextBox
and DataGrid
controls are created like UserControl
s, but are actually classes that inherit TextBox
and DataGrid
, like this: TextBox
和DataGrid
控件的创建方式与UserControl
类似,但实际上是继承TextBox
和DataGrid
,如下所示:
<TextBox ... </TextBox>
and和
public partial class TextBox : System.Windows.Controls.TextBox
As I said, XAML
solution is desired, but I will also settle for a code one, if former is not possible.正如我所说,
XAML
解决方案是需要的,但如果前者不可能,我也将解决一个代码。
Okay, the Dispatcher part from Keyur PATEL's answer was the solution for me, although not the complete one.
好的, Keyur PATEL回答中的 Dispatcher 部分对我来说是解决方案,尽管不是完整的解决方案。 The answer for me was to update
TabControl
layout with the Dispatcher
and than invoke the Focus
Dispatcher
.我的答案是使用
Dispatcher
更新TabControl
布局,然后调用Focus
Dispatcher
。 So, the complete answer for me was:所以,对我来说,完整的答案是:
Dispatcher.BeginInvoke( (Action) (() => tc.UpdateLayout()) );
Dispatcher.BeginInvoke( (Action) (() => txt.Focus() ) );
or you can use just Invoke
instead, for the UI thread to wait for your Action
.或者您可以只使用
Invoke
来让 UI 线程等待您的Action
。
And for the reason why I had to use a Dispatcher
, it is because I used it to change the selected tab in the first place.之所以必须使用
Dispatcher
,是因为我首先用它来更改选定的选项卡。 That is my best guess, at least.至少,这是我最好的猜测。
You could try something similar to your code-behind solution but with this variation:您可以尝试类似于您的代码隐藏解决方案的方法,但具有以下变化:
<TabControl x:Name="tc" SelectionChanged="tc_selectionChanged">
and in code behind:并在后面的代码中:
InitializeComponent();
//if you know which control to focus by default when page is first loaded
Dispatcher.BeginInvoke(new Action(() => { txt.Focus(); }));
and和
private void tc_selectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ti1.IsSelected)
{
txt.Focus();
}
else if (ti2.IsSelected)
{
dg.Focus();
}
}
I tried this exact setup on my own WPF application so I know it works.我在我自己的 WPF 应用程序上尝试了这个确切的设置,所以我知道它有效。
Helpful links:有用的链接:
WPF TabControl On SelectionChanged, set focus to a text field WPF TabControl On SelectionChanged,将焦点设置到文本字段
and和
How to focus control in the tabItem ın WPF (although for me it worked without UpdateLayout()
)如何在 tabItem ın WPF 中集中控制(虽然对我来说它没有
UpdateLayout()
)
Found solution using extension attribute使用扩展属性找到解决方案
public static class TabItemExtention
{
public static bool GetIsSelected(DependencyObject obj)
{
return (bool)obj.GetValue(IsSelectedProperty);
}
public static void SetIsSelected(DependencyObject obj, bool value)
{
obj.SetValue(IsSelectedProperty, value);
}
public static readonly DependencyProperty IsSelectedProperty =
DependencyProperty.RegisterAttached(
"IsSelected", typeof(bool), typeof(TabItemExtention),
new UIPropertyMetadata(false, OnIsSelectedPropertyChanged));
private static void OnIsSelectedPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
var tabItem = uie as TabItem;
if (tabItem != null)
tabItem.IsSelected = (bool)e.NewValue;
if ((bool)e.NewValue)
{
uie.UpdateLayout();
}
}
}
XAML: XAML:
ctrl:TabItemExtention.IsSelected="{Binding IsTabNewCustomsDelaySelected}"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.