У меня есть TextBox
и есть Button
на мой взгляд.
Теперь я проверяю условие при нажатии кнопки, и если условие оказывается ложным, отображаю сообщение пользователю, а затем мне нужно установить курсор на TextBox
элемент управления.
if (companyref == null)
{
var cs = new Lipper.Nelson.AdminClient.Main.Views.ContactPanels.CompanyAssociation();
MessageBox.Show("Company does not exist.", "Error", MessageBoxButton.OK,
MessageBoxImage.Exclamation);
cs.txtCompanyID.Focusable = true;
System.Windows.Input.Keyboard.Focus(cs.txtCompanyID);
}
Приведенный выше код находится в ViewModel.
Это CompanyAssociation
имя представления.
Но курсор не устанавливается в TextBox
.
XAML:
<igEditors:XamTextEditor Name="txtCompanyID"
KeyDown="xamTextEditorAllowOnlyNumeric_KeyDown"
ValueChanged="txtCompanyID_ValueChanged"
Text="{Binding Company.CompanyId,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Width="{Binding ActualWidth, ElementName=border}"
Grid.Column="1" Grid.Row="0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
Margin="0,5,0,0"
IsEnabled="{Binding Path=IsEditable}"/>
<Button Template="{StaticResource buttonTemp1}"
Command="{Binding ContactCommand}"
CommandParameter="searchCompany"
Content="Search"
Width="80"
Grid.Row="0" Grid.Column="2"
VerticalAlignment="Top"
Margin="0"
HorizontalAlignment="Left"
IsEnabled="{Binding Path=IsEditable}"/>
Ответы:
Позвольте мне ответить на ваш вопрос в трех частях.
Мне интересно, что такое "cs.txtCompanyID" в вашем примере? Это элемент управления TextBox? Если да, то вы ошиблись. Вообще говоря, не рекомендуется иметь какую-либо ссылку на пользовательский интерфейс в вашей ViewModel. Вы можете спросить "Почему?" но это еще один вопрос для публикации в Stackoverflow :).
Лучший способ отследить проблемы с Focus - это ... отладка исходного кода .Net. Без шуток. Это много раз экономило мне много времени. Чтобы включить отладку исходного кода .net, обратитесь к блогу Шона Брука .
Наконец, общий подход, который я использую для установки фокуса из ViewModel, - это прикрепленные свойства. Я написал очень простое вложенное свойство, которое можно установить на любом UIElement. И его можно связать, например, со свойством ViewModel IsFocused. Вот:
Теперь в вашем представлении (в XAML) вы можете привязать это свойство к вашей ViewModel:
Надеюсь это поможет :). Если это не относится к ответу №2.
Приветствия.
источник
Keyboard.Focus(uie);
с вашегоOnIsFocusedPropertyChanged
мероприятия, если вы хотите, чтобы ваше управление получило Keyboard Focus, а также Logical Focus...if ((bool)e.NewValue && uie.Dispatcher != null) { uie.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => uie.Focus())); // invoke behaves nicer, if e.g. you have some additional handler attached to 'GotFocus' of UIE. uie.SetValue(IsFocusedProperty, false); // reset bound value if possible, to allow setting again ...
Иногда мне даже нужно сбросить IsFocused на false в ViewModel, если я хочу установить фокус несколько раз. Но тогда он работает там, где другие методы не помогли.public bool IsFocused { get { return _isFocused; } set { if (_isFocused == value) { _isFocused = false; OnPropertyChanged(); } _isFocused = value; OnPropertyChanged(); } }
Я знаю, что на этот вопрос уже тысячи раз ответили, но я внес некоторые правки в статью Анваки, которая, я думаю, поможет другим, у которых были похожие проблемы, которые были у меня.
Во-первых, я изменил указанное выше вложенное свойство следующим образом:
Причиной добавления ссылок на видимость были вкладки. По-видимому, если вы использовали прикрепленное свойство на любой другой вкладке за пределами изначально видимой вкладки, присоединенное свойство не работало, пока вы вручную не сфокусировали элемент управления.
Другим препятствием было создание более элегантного способа сброса базового свойства на false при потере фокуса. Вот тут и появились события потери фокуса.
Если есть лучший способ решить проблему с видимостью, дайте мне знать.
Примечание. Спасибо Apfelkuacha за предложение поместить BindsTwoWayByDefault в DependencyProperty. Я сделал это давно в своем собственном коде, но никогда не обновлял этот пост. Из-за этого изменения Mode = TwoWay больше не требуется в коде WPF.
источник
fe.Dispatcher.BeginInvoke(new Action(() => { fe.Focus(); }), DispatcherPriority.Loaded);
то, что он обновляется после загрузки. Подробнее здесь: telerik.com/forums/isfocused-property#OXgFYZFOg0WZ2rxidln61QЯ думаю, что лучший способ - сохранить чистоту принципа MVVM, поэтому в основном вы должны использовать класс Messenger, предоставляемый с MVVM Light, и вот как его использовать:
в вашей модели просмотра (exampleViewModel.cs): напишите следующее
теперь в вашем View.cs (а не в XAML view.xaml.cs) напишите следующее в конструкторе
этот метод работает нормально, с меньшим количеством кода и поддержкой стандартов MVVM
источник
Ни один из них не сработал для меня точно, но для других я написал это на основе некоторого кода, уже предоставленного здесь.
Использование будет следующим:
А реализация была бы такой:
источник
Это старый поток, но, похоже, нет ответа с кодом, который решает проблемы с принятым ответом Anavanka: он не работает, если вы установите для свойства в модели просмотра значение false или если вы установите для своего свойства значение true, пользователь вручную щелкает что-то еще, а затем вы снова устанавливаете для него значение true. Я также не мог заставить решение Zamotic работать надежно в этих случаях.
Собрав вместе некоторые из приведенных выше обсуждений, я получаю приведенный ниже код, который, как мне кажется, решает эти проблемы:
Тем не менее, это все еще сложно для чего-то, что можно сделать одной строкой в выделенном коде, и CoerceValue на самом деле не предназначен для использования таким образом, поэтому, возможно, выделенный код - это выход.
источник
В моем случае FocusExtension не работал, пока я не изменил метод OnIsFocusedPropertyChanged. Исходный работал только при отладке, когда точка останова останавливала процесс. Во время выполнения процесс идет слишком быстро и ничего не происходит. Благодаря этой небольшой модификации и помощи нашего друга Task, это отлично работает в обоих сценариях.
источник
Проблема в том, что если для IsUserNameFocused установлено значение true, оно никогда не будет ложным. Это решает проблему, обрабатывая GotFocus и LostFocus для FrameworkElement.
У меня возникли проблемы с форматированием исходного кода, вот ссылка
источник
Великолепный код Anvakas предназначен для настольных приложений Windows. Если вы похожи на меня и вам нужно такое же решение для приложений Магазина Windows, этот код может вам пригодиться:
источник
Для тех, кто пытался использовать решение Anvaka выше, у меня были проблемы с привязкой, работающей только в первый раз, поскольку lostfocus не обновлял свойство до false. Вы можете вручную установить для свойства значение false, а затем true каждый раз, но лучшим решением могло бы быть выполнение чего-то вроде этого в своем свойстве:
Таким образом, вам нужно только установить для него значение true, и оно получит фокус.
источник
Я использую WPF / Caliburn Micro, и обнаружил, что dfaivre представил здесь общее и работоспособное решение: http://caliburnmicro.codeplex.com/discussions/222892
источник
Я нашел решение, отредактировав код, как показано ниже. Нет необходимости устанавливать свойство Binding сначала False, затем True.
источник
Для Silverlight:
LoginViewModel.cs:
Login.xaml:
ИЛИ
Чтобы установить фокус, нужно просто сделать это в коде:
Помните, что этот плагин является частью html-страницы, поэтому другие элементы управления на странице могут иметь фокус.
источник
Вы можете использовать ViewCommand проектирования . Он описывает метод шаблона проектирования MVVM для управления представлением из ViewModel с помощью команд.
Я реализовал его на основе предложения короля А. Маджида использовать класс MVVM Light Messenger. Класс ViewCommandManager обрабатывает вызов команд в подключенных представлениях. По сути, это другое направление обычных команд, для тех случаев, когда ViewModel необходимо выполнить какое-то действие в своем View. Он использует отражение, такое как команды с привязкой к данным и WeakReferences, чтобы избежать утечек памяти.
http://dev.unclassified.de/source/viewcommand (также опубликовано на CodeProject)
источник
Кажется, никто не включил последний шаг, чтобы упростить обновление атрибутов с помощью связанных переменных. Вот что я придумал. Дайте мне знать, если есть лучший способ сделать это.
XAML
ViewModel
источник
Прежде всего, я хотел бы поблагодарить Аванку за помощь в решении моей проблемы с фокусировкой. Однако в опубликованном им коде есть ошибка, а именно в строке: if (e.OldValue == null)
Проблема, с которой я столкнулся, заключалась в том, что если вы сначала щелкнете в своем представлении и сфокусируете элемент управления, e.oldValue больше не будет нулевым. Затем, когда вы устанавливаете переменную для фокусировки элемента управления в первый раз, это приводит к тому, что обработчики lostfocus и gotfocus не устанавливаются. Мое решение было следующим:
источник
Просто сделай это:
источник
После реализации принятого ответа я столкнулся с проблемой, что при навигации по представлениям с помощью Prism TextBox по-прежнему не фокусировался. Небольшое изменение в обработчике PropertyChanged решило эту проблему.
источник
Альтернативный подход, основанный на ответе @Sheridan здесь
В вашей модели представления настройте привязку обычным способом, а затем установите SomeTextIsFocused в значение true, чтобы установить фокус на текстовом поле.
источник
Я нашел Crucial решение проблемы IsVisible от очень полезным. Это не решило полностью мою проблему, но кое-какой дополнительный код, следующий по тому же шаблону, что и шаблон IsEnabled, помог.
К методу IsFocusedChanged я добавил:
А вот и обработчик:
источник
источник
источник