簡體   English   中英

WPF MVVM:TextBox需要格式和將IsDefault設置為True的Button

[英]WPF MVVM: TextBox needing format and Button with IsDefault set to True

我發現了有關類似問題的此鏈接 ,除了我的文本框失去焦點后,需要具有格式化值的文本框增加了一些扭曲。

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

用戶在文本框中輸入文本后,我想使用用戶定義的掩碼設置其格式。 例如,如果蒙版為“ 00000”,則約定為右對齊和零填充。

123 => 00123
A01 => 00A01
等等...

我遇到的問題是,當用戶完成鍵入后,我應該只格式化一次文本。 當前,如果用戶單擊按鈕,則將用戶輸入的值推入綁定並執行命令。 但是,如果他們按“ Enter”鍵,則該值不會被推送到綁定中,並且該命令仍會執行。

我找到了如何在用戶按下Enter鍵時推動綁定的唯一方法是更改​​文本框的綁定並指定UpdateSourceTrigger=PropertyChanged 這不能很好地工作,因為我實際上不知道用戶何時輸入完文本。

最簡單的解決方案是在按下回車鍵時在代碼后面添加代碼以設置按鈕的焦點,但是我希望焦點保持在它們當前所在的文本框中。 有沒有人可以解決這個問題,也許是附屬財產?

編輯:

這是我的視圖模型如何格式化輸入值的簡短示例。

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();
        }
    }
}

如果我以正確的方式理解了您的意圖,那么實際上沒有問題。

您只想在用戶按下Enter鍵/右鍵單擊按鈕時屏蔽輸入? 然后,您已經找到的解決方案(UpdateSourceTrigger = PropertyChanged)將完全按照您的意圖進行。 鍵入時,VM中的屬性會更新。 如果您使用PropertyChanged觸發器,則在您按Enter /單擊按鈕之前,該命令將不會執行。

默認的UpdateSourceTrigger是'LostFocus'。 當然,如果您用鼠標單擊按鈕,而不是按Enter鍵,也會發生這種情況。

希望我能幫助您理解該機制。

你看起來不太對勁。 如果命令更新了文本,則在鍵入時不會執行該命令,直到您按Enter /單擊按鈕。

風景:

<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>

viewmodel,在構造函數中被分配為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);
        }

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM