WPF MVVM: TextBox нужен формат и кнопка с IsDefault установлена ​​в True - PullRequest
1 голос
/ 31 августа 2010

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

<TextBox Text="{Binding Value}" MaxLength="{Binding MaskLength}"/>
<Button Command="{Binding ExecuteCommand}" IsDefault="True"/>

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

123 => 00123
A01 => 00A01
и т.д ...

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

Единственный способ узнать, как нажать привязку, когда пользователь нажимает клавишу ввода, - это изменить привязку текстового поля и указать UpdateSourceTrigger=PropertyChanged. Это не очень хорошо работает, потому что я не знаю, когда пользователь закончил вводить свой текст.

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

EDIT:

Вот краткий пример того, как моя модель представления форматирует введенное значение.

public string Value
{
    get
    {
        return mFieldValue;
    }
    set
    {
        SetValueAndRaisePropertyChange( 
            ref mFieldValue, 
            _ApplyFormat( value ), 
            () => FieldValue );
    }
}

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

private void _HandleTxtKeyDown( object sender, KeyEventArgs e )
{
    if( e.Key == Key.Enter )
    {
        TextBox textBox = (TextBox)sender;
        BindingExpression binding = textBox.GetBindingExpression( TextBox.TextProperty );
        if( binding != null )
        {
            binding.UpdateSource();
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 31 августа 2010

Вы не правы.Если команда обновляет текст, она не выполняется во время ввода, пока вы не нажмете клавишу ввода / нажмете кнопку.

Представление:

<Window x:Class="WpfApplication9.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <TextBox MaxLength="{Binding Path=MyLength}" 
                 Text="{Binding Path=MyText, UpdateSourceTrigger=PropertyChanged}"/>

        <Button Command="{Binding Path=MyCommand}" IsDefault="True">Enter</Button>
    </StackPanel>
 </Window>

Модель представления, которая назначена в качестве окнаDataContext в конструкторе:

public class MyViewModel : INotifyPropertyChanged
{
    private string _myText = string.Empty;
    private int _maxLength = 6;
    private ICommand _myCommand;

    public MyViewModel()
    {
        this._myCommand = new MySimpleCommand((obj) => { FormatMyText(); });
    }

    private void FormatMyText()
    {
        this.MyText = this.MyText.PadLeft(this.MyLength, '0');
    }

    public string MyText
    {
        get { return this._myText; }
        set
        {
            this._myText = value;
            PropertyChanged(this, new PropertyChangedEventArgs("MyText"));
        }
    }

    public int MyLength
    {
        get { return this._maxLength; }
        set { }
    }

    public ICommand MyCommand
    {
        get { return this._myCommand; }
        set { }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public class MySimpleCommand : ICommand
    {
        private Action<object> _action;

        public MySimpleCommand(Action<object> cmdAction)
        {
            this._action = cmdAction;
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _action(parameter);
        }

    }
}
0 голосов
/ 31 августа 2010

Если я правильно понял ваше намерение, то проблем нет.

Вы хотите замаскировать ввод, только если пользователь нажимает клавишу ввода / нажимает кнопку справа? Тогда решение, которое вы уже нашли (UpdateSourceTrigger = PropertyChanged), будет делать именно то, что вы намереваетесь. Свойство в вашей виртуальной машине обновляется, пока вы печатаете. Команда не будет выполнена, пока вы не нажмете ввод / нажатие кнопки, если используете триггер PropertyChanged.

По умолчанию UpdateSourceTrigger - «LostFocus». Это, конечно, также происходит, если вы нажимаете кнопку мышью, а не нажатием клавиши ввода.

Надеюсь, я смогу помочь вам понять механизм.

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