MVVM Focus To Textbox - PullRequest
       17

MVVM Focus To Textbox

9 голосов
/ 14 мая 2010

Как бы установить фокус на TextBox без указания имени для TextBox? На данный момент я делаю следующее

<Window FocusManager.FocusedElement="{Binding ElementName=Username}">
    <Grid>
        <TextBox Text="{Binding Username}" Name="Username" />            
    </Grid>
</Window>

Есть ли способ сделать это без указания имени для TextBox. Как я полагаю, в MVVM наличие элемента Name обычно означает плохой дизайн?

Ответы [ 6 ]

22 голосов
/ 21 мая 2010

Как я полагаю, MVVM с элементом Name обычно означает плохой дизайн?

Нет, это не так.

Шаблон MVVM не предназначен для удаления всего кода из файлов с выделенным кодом.

Речь идет о разделении интересов и повышении тестируемости. Представление связанного кода, например, обработка фокуса, должно оставаться в файле выделенного кода представления. Но было бы плохо видеть логику приложения или управление подключением к базе данных в файле с выделенным кодом в представлении.

Примеры MVVM с кодом в файлах с выделенным кодом без нарушения шаблона MVVM можно найти в WPF Application Framework (WAF) проект.

6 голосов
/ 06 августа 2013

Простой способ - установить фокус в событии UserControl_Load

        this.txtBox.Focus();
        txtBox.Focusable = true;
        Keyboard.Focus(txtBox);

MVVM не означает, что вы не можете поместить код в код позади файла.На самом деле, не позволяйте никаким шаблонам ограничивать вас, чтобы найти лучший способ кодирования.

3 голосов
/ 09 января 2015

Следует избегать кода позади, когда это возможно, даже больше, когда он находится в поле зрения. У меня была та же проблема, и для простых целей лучший ответ - это тот, который только изменяет представление:

WPF MVVM Фокус по умолчанию на текстовом поле и выберитеВсе

Если вы хотите снова установить фокус при взаимодействии с другими элементами UserControl, это поможет:

Установить фокус на текстовое поле в WPF из модели представления (C #)

Я потерял 3 дня, чтобы понять это, я надеюсь, что это может помочь.

3 голосов
/ 14 мая 2010

Я задокументировал «чистый MVVM» способ сделать это в своем ответе на похожую проблему . Решение включает использование Attached Properties и инфраструктуры для передачи интерфейсных команд из ViewModel обратно в View.

0 голосов
/ 20 ноября 2013

Как я полагаю, MVVM, имеющий элемент Name, обычно означает плохой дизайн?

Нет, это не так.

По мнению Microsoft MVP, управление именами - это не только плохая практика WPF, но и существенное снижение производительности. Просто хотел передать некоторые слова мудрости

Я согласен с Шоном Ду в том, что нельзя позволять каким-либо шаблонам полностью ограничивать вас, я думаю, что следует избегать снижения производительности при любой возможности.

0 голосов
/ 27 августа 2013

На самом деле, я нашел решение с булевыми вложенными свойствами немного грязным и неуклюжим в том смысле, что вам нужно найти поворот, чтобы быть уверенным, что следующий набор вашего свойства модели представления действительно вызовет событие изменения присоединенного свойства.

Простое и более элегантное решение - связать ваше поведение с типом свойства, для которого вы можете быть уверены, что следующее значение всегда будет отличаться от предыдущего, и, таким образом, быть уверенным, что событие изменения присоединенного свойства будет вызываться каждый раз.

Самый простой тип, который приходит на ум, это int. Решение тогда - обычная комбинация:

Поведение:

public static class TextBoxFocusBehavior
{
    public static int GetKeepFocus(DependencyObject obj)
    {
        return (int)obj.GetValue(KeepFocusProperty);
    }

    public static void SetKeepFocus(DependencyObject obj, int value)
    {
        obj.SetValue(KeepFocusProperty, value);
    }

    // Using a DependencyProperty as the backing store for KeepFocus.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty KeepFocusProperty =
        DependencyProperty.RegisterAttached("KeepFocus", typeof(int), typeof(TextBoxFocusBehavior), new UIPropertyMetadata(0, OnKeepFocusChanged));

    private static void OnKeepFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBox t = d as TextBox;
        if (t != null)
        {
            t.Focus();
        }
    }
}

Свойство модели просмотра:

    public int InputFocus
    {
        get { return _inputFocus; }
        private set
        {
            _inputFocus = value;
            Notify(Npcea.InputFocus);
        }
    }

Использование прикрепленного поведения:

 <TextBox  v:TextBoxFocusBehavior.KeepFocus="{Binding InputFocus}"/>

И, наконец, использование имущества в ВМ:

    public void YouMethod()
    {
        //some code logic
        InputFocus++;//<= the textbox focus
    }

Некоторые ДЕЙСТВИТЕЛЬНО злые духи могут сказать, что эта логика связана с ограничением размера int32. Ну ... я сейчас просто проигнорирую их; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...