Если вы используете Caliburn.Micro, вот служба, которую я создал для установки Фокуса на любой элемент управления в представлении, унаследованном от Screen.
Примечание: Это будет работать только в том случае, если вы используете Caliburn.Micro для своей инфраструктуры MVVM.
public static class FocusManager
{
public static bool SetFocus(this IViewAware screen ,Expression<Func<object>> propertyExpression)
{
return SetFocus(screen ,propertyExpression.GetMemberInfo().Name);
}
public static bool SetFocus(this IViewAware screen ,string property)
{
Contract.Requires(property != null ,"Property cannot be null.");
var view = screen.GetView() as UserControl;
if ( view != null )
{
var control = FindChild(view ,property);
bool focus = control != null && control.Focus();
return focus;
}
return false;
}
private static FrameworkElement FindChild(UIElement parent ,string childName)
{
// Confirm parent and childName are valid.
if ( parent == null || string.IsNullOrWhiteSpace(childName) ) return null;
FrameworkElement foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for ( int i = 0; i < childrenCount; i++ )
{
FrameworkElement child = VisualTreeHelper.GetChild(parent ,i) as FrameworkElement;
if ( child != null )
{
BindingExpression bindingExpression = GetBindingExpression(child);
if ( child.Name == childName )
{
foundChild = child;
break;
}
if ( bindingExpression != null )
{
if ( bindingExpression.ResolvedSourcePropertyName == childName )
{
foundChild = child;
break;
}
}
foundChild = FindChild(child ,childName);
if ( foundChild != null )
{
if ( foundChild.Name == childName )
break;
BindingExpression foundChildBindingExpression = GetBindingExpression(foundChild);
if ( foundChildBindingExpression != null &&
foundChildBindingExpression.ResolvedSourcePropertyName == childName )
break;
}
}
}
return foundChild;
}
private static BindingExpression GetBindingExpression(FrameworkElement control)
{
if ( control == null ) return null;
BindingExpression bindingExpression = null;
var convention = ConventionManager.GetElementConvention(control.GetType());
if ( convention != null )
{
var bindablePro = convention.GetBindableProperty(control);
if ( bindablePro != null )
{
bindingExpression = control.GetBindingExpression(bindablePro);
}
}
return bindingExpression;
}
}
Как использовать это?
От вашей ViewModel, унаследованной от Caliburn.Micro.Screen или Caliburn.Micro.ViewAware
this.SetFocus(()=>ViewModelProperty);
или this.SetFocus("Property");
Как это работает?
Этот метод попытается найти элемент в VisualTree of View и focus будут установлены на любой соответствующий элемент управления.Если такой элемент управления не найден, он будет использовать BindingConventions, используемую Caliburn.Micro.
Например,
Он будет искать свойства в выражении BindingExpression элемента управления.Для TextBox будет проверено, привязано ли это свойство к свойству Text, затем будет установлен фокус.