单击时如何将焦点设置到内容控件中的文本框?
How to set focus to a textbox within content control when clicked?
我有一个视图,其中包含视图中的两个视图(它们包含在 ContainerControl 中)。
在视图的另一侧有一个 Telerik GridView,用户可以在其中 select 一行。当一行被 selected 时,视图的另一侧会动态更改为另一个视图(和 ViewModel)。动态视图是一个带有大量文本框的简单网格,因此没有什么特别之处。
现在,当用户想要向动态加载的视图输入值时,他必须先单击 ContentControl
,然后再次单击他想要聚焦的 TextBox
。这仅在 GridView 的行处于 编辑模式 .
时发生
我试过设置 ContentControl 的 FocusManager.IsFocusScope="False"
。
我还尝试使用 IsFocusable=False
设置所有其他控件。
我知道一定有一种方法可以用 WPF 事件做到这一点,但我不是这方面的专家。
我像这样使用 Catel 的转换器设置动态视图(不知道它是否相关):
XAML:
<ContentControl Content="{Binding SelectedItemViewModel, Mode=TwoWay, Converter={catel:ViewModelToViewConverter}}" />
视图模型:
public MyDataModel SelectedItem
{
get { return GetValue<MyDataModel>(SelectedItemProperty); }
set
{
SetValue(SelectedItemProperty, value);
RaisePropertyChanged(() => SelectedItemViewModel);
}
}
public static readonly PropertyData SelectedItemProperty = RegisterProperty("SelectedItem", typeof(MyDataModel));
public ViewModelBase SelectedItemViewModel
{
get
{
if (SelectedItem != null)
{
switch (SelectedItem.Type)
{
case 1:
return new OneViewModel(SelectedItem);
case 2:
return new TwoViewModel(SelectedItem);
}
}
return null;
}
}
这有点奇怪。焦点应设置为鼠标单击时的控件,而不是内容控件。我不确定你做错了什么。我尝试了一个示例应用程序,它按预期工作。
This thread表示没有好的解决办法。唯一的选择是在控件的模板中将内容控件的 IsTabStop
属性 设置为 False
,然后添加一个新的 属性 IsChildTabStop
子部分会被绑定。不知道对你有没有帮助。
参考: MSDN Forum
好的,这是一个简单的解决方案 - 不是一个漂亮的解决方案:
这只是正确答案 - 如果您只想让 TextBox
在加载视图后拥有 Focus
。
XAML
<UserControl x:Class="WpfApplication4.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox Loaded="TextBox_Loaded"/>
</Grid>
</UserControl>
代码隐藏
private void TextBox_Loaded(object sender, RoutedEventArgs e)
{
TextBox self = sender as TextBox;
if (self != null)
self.Focus();
}
正如我所说 - 这是解决方法
我通过删除外部视图(不同的 xaml 文件)引用并将视图合并为一个大的 xaml 解决了这个问题。出于某种原因,Telerik 的 gridiview "stole" 来自引用视图的光标,但是当所有控件都在同一个 xaml 文件上时,一切都按预期工作。
我有一个视图,其中包含视图中的两个视图(它们包含在 ContainerControl 中)。 在视图的另一侧有一个 Telerik GridView,用户可以在其中 select 一行。当一行被 selected 时,视图的另一侧会动态更改为另一个视图(和 ViewModel)。动态视图是一个带有大量文本框的简单网格,因此没有什么特别之处。
现在,当用户想要向动态加载的视图输入值时,他必须先单击 ContentControl
,然后再次单击他想要聚焦的 TextBox
。这仅在 GridView 的行处于 编辑模式 .
我试过设置 ContentControl 的 FocusManager.IsFocusScope="False"
。
我还尝试使用 IsFocusable=False
设置所有其他控件。
我知道一定有一种方法可以用 WPF 事件做到这一点,但我不是这方面的专家。
我像这样使用 Catel 的转换器设置动态视图(不知道它是否相关):
XAML:
<ContentControl Content="{Binding SelectedItemViewModel, Mode=TwoWay, Converter={catel:ViewModelToViewConverter}}" />
视图模型:
public MyDataModel SelectedItem
{
get { return GetValue<MyDataModel>(SelectedItemProperty); }
set
{
SetValue(SelectedItemProperty, value);
RaisePropertyChanged(() => SelectedItemViewModel);
}
}
public static readonly PropertyData SelectedItemProperty = RegisterProperty("SelectedItem", typeof(MyDataModel));
public ViewModelBase SelectedItemViewModel
{
get
{
if (SelectedItem != null)
{
switch (SelectedItem.Type)
{
case 1:
return new OneViewModel(SelectedItem);
case 2:
return new TwoViewModel(SelectedItem);
}
}
return null;
}
}
这有点奇怪。焦点应设置为鼠标单击时的控件,而不是内容控件。我不确定你做错了什么。我尝试了一个示例应用程序,它按预期工作。
This thread表示没有好的解决办法。唯一的选择是在控件的模板中将内容控件的 IsTabStop
属性 设置为 False
,然后添加一个新的 属性 IsChildTabStop
子部分会被绑定。不知道对你有没有帮助。
参考: MSDN Forum
好的,这是一个简单的解决方案 - 不是一个漂亮的解决方案:
这只是正确答案 - 如果您只想让 TextBox
在加载视图后拥有 Focus
。
XAML
<UserControl x:Class="WpfApplication4.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox Loaded="TextBox_Loaded"/>
</Grid>
</UserControl>
代码隐藏
private void TextBox_Loaded(object sender, RoutedEventArgs e)
{
TextBox self = sender as TextBox;
if (self != null)
self.Focus();
}
正如我所说 - 这是解决方法
我通过删除外部视图(不同的 xaml 文件)引用并将视图合并为一个大的 xaml 解决了这个问题。出于某种原因,Telerik 的 gridiview "stole" 来自引用视图的光标,但是当所有控件都在同一个 xaml 文件上时,一切都按预期工作。