[英]WPF Initial focus for each TabItem
好的,我知道这个标题看起来像是在 SO 周围都有答案,但是这里找到的答案都没有对我有用。 所以,这就开始了。
我有这个布局:
<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>
现在,我的目标是把重点放在txt
TextBox
时ti1
TabItem
被选中,并在dg
DataGrid
当ti2
TabItem
被选中。 另外,我真的很想在XAML
设置它。
注意:我只能使用此处命名的控件,直到Page
控件为止。
到目前为止我尝试了什么:
txt
Control
的父树中的所有父控件上设置FocusManager.FocusedElement="{Binding ElementName=txt}"
(直到Page
)。txt
和dg
控件上设置FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
。 通过TabControl
的SelectionChanged
事件在代码中设置焦点:
TextBox
和DataGrid
控件的创建方式与UserControl
类似,但实际上是继承TextBox
和DataGrid
,如下所示:
<TextBox ... </TextBox>
和
public partial class TextBox : System.Windows.Controls.TextBox
正如我所说, XAML
解决方案是需要的,但如果前者不可能,我也将解决一个代码。
好的, Keyur PATEL回答中的 Dispatcher 部分对我来说是解决方案,尽管不是完整的解决方案。 我的答案是使用Dispatcher
更新TabControl
布局,然后调用Focus
Dispatcher
。 所以,对我来说,完整的答案是:
Dispatcher.BeginInvoke( (Action) (() => tc.UpdateLayout()) );
Dispatcher.BeginInvoke( (Action) (() => txt.Focus() ) );
或者您可以只使用Invoke
来让 UI 线程等待您的Action
。
之所以必须使用Dispatcher
,是因为我首先用它来更改选定的选项卡。 至少,这是我最好的猜测。
您可以尝试类似于您的代码隐藏解决方案的方法,但具有以下变化:
<TabControl x:Name="tc" SelectionChanged="tc_selectionChanged">
并在后面的代码中:
InitializeComponent();
//if you know which control to focus by default when page is first loaded
Dispatcher.BeginInvoke(new Action(() => { txt.Focus(); }));
和
private void tc_selectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ti1.IsSelected)
{
txt.Focus();
}
else if (ti2.IsSelected)
{
dg.Focus();
}
}
我在我自己的 WPF 应用程序上尝试了这个确切的设置,所以我知道它有效。
有用的链接:
WPF TabControl On SelectionChanged,将焦点设置到文本字段
和
如何在 tabItem ın WPF 中集中控制(虽然对我来说它没有UpdateLayout()
)
使用扩展属性找到解决方案
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:
ctrl:TabItemExtention.IsSelected="{Binding IsTabNewCustomsDelaySelected}"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.