【发布时间】:2012-03-21 13:47:10
【问题描述】:
我有 MyContainer 用户控件,里面有 Grid。此 Grid 的每个单元格都包含一个派生自 MyControlBase 类的一些控件。这些控件是动态添加的。
我需要在 MyContainer 中实现一个 FocusedControl 绑定属性以获取当前焦点或将焦点设置到任何 MyControlBase 子级。我知道 FocusManager.FocusedElement,但不知道如何正确实现它。
【问题讨论】:
我有 MyContainer 用户控件,里面有 Grid。此 Grid 的每个单元格都包含一个派生自 MyControlBase 类的一些控件。这些控件是动态添加的。
我需要在 MyContainer 中实现一个 FocusedControl 绑定属性以获取当前焦点或将焦点设置到任何 MyControlBase 子级。我知道 FocusManager.FocusedElement,但不知道如何正确实现它。
【问题讨论】:
不知道这是否对您的情况有所帮助,或者它是否是解决我的问题的正确方法,但在紧要关头,我发现在我想要关注的对象上侦听 Loaded 事件,然后使用 Dispatcher.BeginInvoke 来当其他方法没有工作时,向我的后台或 ApplicationIdle 优先级的控件发送一个焦点请求。例如:
private void MyControlLoaded(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action( () => MyControl.Focus() ));
}
【讨论】:
好的,我自己找到了方法。
首先像往常一样定义我们的新依赖属性FocusedAdapterProperty:
public static readonly DependencyProperty FocusedAdapterProperty;
static SpreadGridControl()
{
FocusedAdapterProperty = DependencyProperty.Register("FocusedAdapter",
typeof(object), typeof(SpreadGridControl),
new FrameworkPropertyMetadata(null, null));
}
public object FocusedAdapter
{
get { return GetValue(FocusedAdapterProperty); }
set { SetValue(FocusedAdapterProperty, value); }
}
接下来将 GotFocus 处理程序添加到父容器,例如<Grid GotFocus="Grid_OnGotFocus">
检查 e.OriginalSource 并搜索所需类型的最常见祖先并将属性设置为新值:
private void Grid_OnGotFocus(object sender, RoutedEventArgs e)
{
var control = UIHelpers.TryFindParent<ControlBase>
((DependencyObject)e.OriginalSource);
if (control != null)
FocusedAdapter = control.Adapter;
}
TryFindParent的实现可以参考here
【讨论】: