我正在为我的应用程序使用MVVM,并且有一个允许用户输入基本人员信息的表单。该表单包括一个UserControl,它基本上是一个ItemsControl,包含可以动态创建的textBoxes。这是一个简化版本:
<ItemsControl x:Name="items" ItemsSource="{Binding MyItemsCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="row">
<TextBox x:Name="textBox" Text="{Binding ContactInfo, ValidatesOnExceptions=True}" extensions:FocusExtension.IsFocused="{Binding IsFocused}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button x:Name="NewItemButton" Command="{Binding AddItemToMyCollectionCommand}" />
我希望刚刚创建的TextBox获得焦点,因此我添加了一个附加属性。这是其中的一部分:
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusExtension), new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
{
uie.Focus();
}
}
在包含UserControl的表单中,前后还有其他几个文本框。 UserControl有自己的ViewModel,我通过容器的ViewModel中的属性将其设置为控件的DataContext。基本上,容器的简化版本如下所示:
<StackPanel Orientation="Horizontal" />
<TextBox x:Name="firstName" />
<TextBox x:Name="lastName" />
<local:DynamicFormUserControl
x:Name="phones"
DataContext="{Binding PhonesViewModel}" />
<local:DynamicFormUserControl
x:Name="emails"
DataContext="{Binding EmailsViewModel}" />
<TextBox x:Name="address" />
</StackPanel>
我的问题是我希望firstName TextBox在第一次加载表单时获得焦点,但表单继续将焦点放在手机UserControl的第一个TextBox上。我尝试通过在表单的Loaded事件上使用firstName.Focus()来覆盖它,但是这不起作用,并且无论我尝试了什么,焦点仍然是手机userControl而不是表单中的第一个元素包含它。
有人知道如何解决这个问题吗?
感谢。
答案 0 :(得分:0)
你去吧
将FocusManager.FocusedElement="{Binding ElementName=firstName}"
添加到您的堆叠面板
<StackPanel Orientation="Horizontal"
FocusManager.FocusedElement="{Binding ElementName=firstName}"/>
<TextBox x:Name="firstName" />
<TextBox x:Name="lastName" />
<local:DynamicFormUserControl
x:Name="phones"
DataContext="{Binding PhonesViewModel}" />
<local:DynamicFormUserControl
x:Name="emails"
DataContext="{Binding EmailsViewModel}" />
<TextBox x:Name="address" />
</StackPanel>
另请注意,您可能需要阻止用户控件中的项控件自行聚焦
<ItemsControl x:Name="items" Focusable="False" >
<ItemsControl.ItemTemplate>
答案 1 :(得分:0)
我想我设法找到了解决方案。问题是我创建的表单本身就是一个窗口内的用户控件,从来没有得到焦点。我不认为那是相关的,所以我在之前的帖子中没有提到它 - 抱歉。我在this解决方案中找到了强制关注用户控件的解决方案。
基本上,当我在窗口中有一个UserControl时,即使我尝试使用Focus()或FocusedElement设置焦点,它也不会获得焦点。所以为了解决这个问题,我在另一篇文章中找到了一个解决方法。基本上我将它添加到包含firstName TextBox的UserControl的代码隐藏。如果我们调用UserControl,比如说,PersonalInfoUserControl,控件的构造函数将如下所示:
public PersonalInfoUserControl()
{
InitializeComponent();
this.IsVisibleChanged += new DependencyPropertyChangedEventHandler(UserControl_IsVisibleChanged);
}
我在控件的IsVisibleChanged事件中添加了一个事件处理程序。该方法如下所示:
void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue == true)
{
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate()
{
firstName.Focus();
}));
}
}