【发布时间】:2014-06-06 14:13:41
【问题描述】:
我在我的应用程序中使用 MVVM,并且有一个允许用户输入基本人员信息的表单。该表单包含一个 UserControl,它基本上是一个 ItemsControl,其中包含可以动态创建的文本框。这是一个简化版:
<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 上,而不是表单中的第一个元素包含它。
有人知道如何解决这个问题吗?
谢谢。
【问题讨论】:
-
像@pushpraj 建议的那样使用
FocusManager.FocusedElement并删除您的附加属性...如果您不想使用它,为什么还要设置它?我也看不出有任何理由在这里使用UserControl……你可以用简单的Styles 和DataTemplates 来完成所有这些工作。请参阅 MSDN 上的[控制创作概述](msdn.microsoft.com/en-us/library/…) 页面,了解何时适合从UserControl派生类。 -
感谢谢里登,您的反馈。我使用 UserControl 的原因是因为我试图在表单中添加一个部分,该部分可以使用 viewModel 中的特定逻辑动态创建更多文本框。我在这里展示的代码是我实际应用程序的精简版。我试图只使用样式但无法弄清楚,所以我在 StackOverflow 中找到了一个使用 UserControls 的解决方案。我有一个附加属性的原因是当一个新的文本框被动态创建时(通过单击控件中的按钮),我希望该框获得焦点。
标签: c# wpf mvvm user-controls