簡體   English   中英

在MVVM中實現textbox lostfocus事件

[英]Implementing textbox lostfocus event in MVVM

我想完成一項簡單的任務。 需要實現textbox lostfocus,當用戶輸入數據時,只要一個字段被填充並且他到達下一個字段,它就應該在前一個字段上激活驗證功能。 另外,我正在使用MVVM模式。

所以我有這門課

public class data : INotifyPropertyChanged
{

    public string name;
    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
            OnPropertyChanged("Name");
        }
    }
    public string firstname;
    public string FirstName
    {
        get
        {
            return firstname;
        }

        set
        {
            firstname = value;
            OnPropertyChanged("FirstName");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            // Raise the PropertyChanged event
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
} 

在Viewmodel中我得到了這個

data1 = new data() { name = "Eddie Vedder", firstname = "Eddie" }; //this line in initialization 
public data _data1;
public data data1
{
    get { return _data1; }
    set 
    {

        _data1 = value;
        ValidateThis();
        NotifyPropertyChanged(new PropertyChangedEventArgs("data1"));
    }
}

在Xaml中:

<StackPanel Orientation="Horizontal" >
    <Label Width="90" Content="Name" Height="28" HorizontalAlignment="Left" Name="lblName" VerticalAlignment="Top" />
    <TextBox Text="{Binding Path=data1.name, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"   MaxLength="40" TabIndex="2" Height="25" Margin="0,3,0,0" HorizontalAlignment="Left" Name="txtName" VerticalAlignment="Top" Width="200" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
    <Label Width="90" Content="First Name" Height="28" HorizontalAlignment="Left" Name="lblFirstName" VerticalAlignment="Top" />
    <TextBox Text="{Binding  Path=data1.firstname, UpdateSourceTrigger=LostFocus, Mode=TwoWay}" MaxLength="40" TabIndex="3" Name="txtFirstName" Height="25" Margin="0,3,0,0" VerticalAlignment="Top" Width="200" >
    </TextBox>
</StackPanel>

當我執行它時,我的綁定工作正如它默認名稱Eddie Vedder。 當我調試它時,它不會輸入類數據。

當你使用MVVM模式時,我假設你有一些綁定來查看模型屬性,它看起來像:Xaml:

<StackPanel>
    <!--Pay attention on UpdateSourceTrigger-->
    <TextBox Text="{Binding Text, UpdateSourceTrigger=LostFocus}" />
    <TextBox />
</StackPanel>

C#:

private string _text;
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        Validate(); // Desired validation
        OnPropertyChanged();
    }
}

如果將UpdateSourceTrigger設置為LostFocus,則在失去焦點時將觸發屬性更改。

有一篇非常好的文章: MVVM WPF命令

首先創建一個類: DelegateCommand.cs

public class DelegateCommand<T> : System.Windows.Input.ICommand where T : class
{
    private readonly Predicate<T> _canExecute;
    private readonly Action<T> _execute;

    public DelegateCommand(Action<T> execute)
     : this(execute, null)
    {
    }

    public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
            return true;

        return _canExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    public event EventHandler CanExecuteChanged;
    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }
}

將委托添加到ViewModel中:

  private readonly DelegateCommand<string> _lostFocusCommand;

  public DelegateCommand<string> LostFocusCommand
  {
     get { return _lostFocusCommand; }
  }
  private string _input;
  public string Input
  {
     get { return _input; }
     set
     {
        _input = value;
     }
  }

並在ViewModel的構造函數中初始化它:

// _input will be the property you have with a binding to the textbox control in the view.
// in the canExecute part add the conditions you want to use to check if the lostfocus command will be raised
 _lostFocusCommand = new DelegateCommand<string>(
  (s) => { /* perform some action */
     MessageBox.Show("The lostfocuscommand works!");
  }, //Execute
  (s) => { return !string.IsNullOrEmpty(_input); } //CanExecute
  );

查看:您需要添加以下命名空間

xmlns:b="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  

和控制

<TextBox Grid.Column="0"
    Text="{Binding Input, UpdateSourceTrigger=PropertyChanged}">
    <b:Interaction.Triggers>
        <b:EventTrigger EventName="LostFocus">
            <b:InvokeCommandAction  Command="{Binding LostFocusCommand}" CommandParameter="{Binding Input}"/>
        </b:EventTrigger>
     </b:Interaction.Triggers>
  </TextBox>

好吧,這有點訣竅

public class Validate
{
    public static ErrorProperties ep = new ErrorProperties();
    public static bool ValidateThis(string PropertyName, string PropertyValue)
    {
        if (PropertyValue.Length > 10)
        {
            ep.ErrorPropertyName = PropertyName;
            return true;
        }
        return false;
    }
}

public class ErrorProperties
{
    public string ErrorPropertyName { get; set; }
    public string Error { get; set; }
}

public class data : INotifyPropertyChanged
{
    private ObservableCollection<ErrorProperties> _ErrorList = new ObservableCollection<ErrorProperties>();
    public ObservableCollection<ErrorProperties> ErrorList
    {
        get
        {
            return _ErrorList;
        }
        set
        {
            if (_ErrorList != value)
            {
                _ErrorList = value;
                OnPropertyChanged("ErrorList");
            }
        }
    }


    private string _Name;
    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            if (_Name != value)
            {
                _Name = value;
                if (Validate.ValidateThis("Name", value))
                    ErrorList.Add(Validate.ep);
                OnPropertyChanged("Name");
            }
        }
    }


    private string _FirstName;
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            if (_FirstName != value)
            {
                _FirstName = value;
                if (Validate.ValidateThis("FirstName", value))
                    ErrorList.Add(Validate.ep);
                OnPropertyChanged("FirstName");

            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            // Raise the PropertyChanged event
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

暫無
暫無

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

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