Ответ 1
Используйте свойство IsFocused Attached Property, как предлагается в ответе здесь: Установите фокус на текстовое поле в WPF из модели просмотра (С#)
Затем вы можете просто привязать свойство к своей модели просмотра.
Какова хорошая практика настройки фокуса управления в архитектуре MVVM.
Как я себе это представляю, это свойство на ViewModel, которое может вызвать изменение фокуса, когда это необходимо. И чем управляющие элементы интерфейса связывают/прослушивают это свойство, так что если он изменится, будет установлен соответствующий фокус.
Я рассматриваю его как объект ViewModel, потому что хочу установить фокус, соответствующий после того, как определенное действие было выполнено ViewModel, например, загрузка определенных данных.
Какая лучшая практика?
Используйте свойство IsFocused Attached Property, как предлагается в ответе здесь: Установите фокус на текстовое поле в WPF из модели просмотра (С#)
Затем вы можете просто привязать свойство к своей модели просмотра.
Если вы используете Caliburn.Micro, вот сервис, который я создал, чтобы установить Focus на любой элемент управления в виде, унаследованном от экрана.
Примечание: Это будет работать, только если вы используете 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");
Как это работает?
Этот метод попытается найти элемент в визуальном дереве просмотра, а фокус будет установлен на любой соответствующий элемент управления. Если такой контроль не найден, тогда он будет использовать BindingConventions, используемые Caliburn.Micro.
Например,
Он будет искать правильность в BindingExpression элемента управления. Для TextBox он будет смотреть, будет ли это свойство привязано к свойству Text, тогда фокус будет установлен.
ViewModel выдает событие в представление, сообщающее ему, что действие завершено, и представление будет устанавливать фокус.
Вы можете ввести интерфейс для представления, чтобы ViewModel мог указать View, чтобы установить Focus. Пример использования BookLibrary приложения WPF Application Framework (WAF) показывает, как это сделать. Посмотрите на BookListViewModel.
Вопрос задан несколько раз, к сожалению, ответы применимы только к WPF. Таким образом, для серебряного света с использованием MVVM вы также можете связываться с любым свойством для подробностей, пожалуйста, перейдите по следующей ссылке
http://codenicely.blogspot.com/2012/01/how-to-set-textbox-focus-in-silverlight.html