从一个签到页面浅淡MVVM,MVVM的大旨技术

在C#中国国际信资公司息有多个针对,一个针对性Message,二个针对INotify。那里根本讲INotify。

接触MVVM接近一段时间了,有有些通晓,写下来。

亚洲必赢官网 1

初识 MVVM

谈到 MVVM 设计形式,概率先影像您会想到
WPF/Sliverlight,他们提供了的多寡绑定(Data
Binding),命令(Command)等功效,那让 MVVM 形式获得很好的达成。
MVVM 设计格局顾名思义,通过分离关怀点,各司其职。通过 Data Binding
可达到数据的双向绑定,而下令 Command 更是将价值观的 Code Behind 事件独立到
ViewModel 中。

亚洲必赢官网 2

INotify也有人称之为[通知],不管叫音信依然公告,皆以2个情趣,就是传递音讯。

前边是做winform的,工作需求,学习wpf。优缺点就无须说类,网上一大堆。笔者本身通晓的话,有上面几点:

如上图,扩展了三个 LoginViewModel.cs
文件,放在 ViewModels 目录中,那几个文件就是 LoginPage 的 ViewModel 。

MVVM 设计形式在 WPF 中的完毕

在WPF中,你会像如下那样去定义多个专门管理视图 View 的 ViewModel:

public class SongViewModel : INotifyPropertyChanged
{
    #region Construction
    /// Constructs the default instance of a SongViewModel
    public SongViewModel()
    {
        _song = new Song { ArtistName = "Unknown", SongTitle = "Unknown" };
    }
    #endregion

    #region Members
    Song _song;
    #endregion

    #region Properties
    public Song Song
    {
        get
        {
            return _song;
        }
        set
        {
            _song = value;
        }
    }

    public string ArtistName
    {
        get { return Song.ArtistName; }
        set
        {
            if (Song.ArtistName != value)
            {
                Song.ArtistName = value;
                RaisePropertyChanged("ArtistName");
            }
        }
    }
    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    #region Methods

    private void RaisePropertyChanged(string propertyName)
    {
        // take a copy to prevent thread issues
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}

并且在 View 中您须要动用 Binding 将 ViewModel
的天性绑定和控件的始末相绑定:

 <TextBox Content="{Binding ArtistName}" />

值得注意的是,要兑现 View 和 ViewModel 双向绑定,大家的 ViewModel
必须贯彻 INotifyPropertyChanged 接口,由于 WPF Framework
让控件监听了 PropertyChanged 事件,当属性值发生时,触发 PropertyChanged
事件,所以控件就能活动获取到最新的值。反之,当控件的值产生改变时,例如
TextBox 触发 OnTextChanged 事件,自动将时尚的值同步到 ViewModel
相应的性质中。

新闻的定义

一、首先是界面包车型地铁xmal和界面分离:wpf也同等支持拖拉控件,可是选择wpf的人,都觉着在xmal中写控件更屌一点。并且能够运用静态财富(Window。Resources)设置每叁个控件的体制(Style),统1界面风格更便于。Style中的TargetType钦定属于某1类控件,Setter钦命属性(Property)和Value。

三个 UI 对应三个 ViewModel ,那正是 MVVM
的渴求,在 ASP.NET MVC 贰 中,就是周围那样的。

MVP & MVVM

Unity 3D 与 WPF/Sliverlight 不一致,它未有提供类似的 Data
Binding,也远非像 XAML 一样的视图语法,那么怎么着才能在 Unity 3D 中去达成MVVM 呢?

在 ASP.NET WebForm 时代,那时还平昔不 ASP.Net MVC 。我们为了让 UI
表现层分离,平日会利用 MVP 设计格局,以下是自家在几年前画的一张老图:
亚洲必赢官网 3

MVP 设计格局核心便是,通过定义贰个 View,将 UI
抽象出来,它不用关怀数据的切切实实来源,也无需关怀点击按钮之后业务逻辑的兑现,它只关注UI 交互。那正是超人的分手关切点。

实质上那正是自作者今天想讲的大旨,既然 Unity 3D
没有提供数据绑定,那么咱们也能够参见从前 MVP 的筹划意见:

将 UI 抽象成单身的2个个 View,将面向 Component 开发转换为面向 View
开发,每二个 View 都有独立的 ViewModel 实行政管理理,如下所示:

亚洲必赢官网 4

鉴于 Unity 3D 尚无 XAML,也尚未 Data Binding 技术,故只辛亏架空出来的
View 中去完结类似于 WPF 的 Data Binding,Converter,Command 等。

值得注意的是,MVP 设计方式中数据的绑定是通过将现实的 View 实例传递到
Presenter 中成就的,而 MVVM 是以多少变动吸引的风云中做到数据更新的。

INotify音信其实是3个接口,接口名称为INotifyPropertyChanged。接口定义如下:

  如  <Style x:key=”TxtBoxStyle” TargetType=“TextBox”>

上面是以此 ViewModel
的某些代码: 

MVVM 设计形式在 Unity 3D 中的设计与落实

再回想一下 WPF 中 ViewModel 的写法。 ViewModel 提供了 View
需求的多少,并且 ViewModel 实现 INotifyPropertyChanged 接口
,当数码变动时,触发了 PropertyChanged
事件,由于控件也监听了此事件,在事变的响应函数里实现数量的创新。

打探了今后,大家要思虑什么在 Unity 3D
中去贯彻它。借使大家须要做到如下的一个效果,并且是选择 MVVM
设计思想贯彻:

亚洲必赢官网 5.gif)

首先,咱们要定义一个 View,那个 View 是对 UI
成分的三个虚无,到底要抽象哪些 UI
成分呢?就那一个事例而言,InputField,Label,Slider,Toggle,Button
是急需被架空出来的。

public class SetupView
{
    public InputField nameInputField;
    public Text nameMessageText;

    public InputField jobInputField;
    public Text jobMessageText;

    public InputField atkInputField;
    public Text atkMessageText;

    public Slider successRateSlider;
    public Text successRateMessageText;

    public Toggle joinToggle;
    public Button joinInButton;
    public Button waitButton;
}

能够见到,那是三个很简单的 View。接着我们须要定义二个专程用来管理 View
的 ViewModel,它以属性的样式提供数据,以艺术的情势提供行为。

值得注意的是,ViewModel
中的属性不是特种的性质,它必须具备当数码变动时通报订阅者这几个作用,怎么告示订阅者?当然是事件,故笔者把此属性称为
BindableProperty 属性。

 public class BindableProperty<T>
{
    public delegate void ValueChangedHandler(T oldValue, T newValue);

    public ValueChangedHandler OnValueChanged;

    private T _value;
    public T Value
    {
        get
        {
            return _value;
        }
        set
        {
            if (!object.Equals(_value, value))
            {
                T old = _value;
                _value = value;
                ValueChanged(old, _value);
            }
        }
    }

    private void ValueChanged(T oldValue, T newValue)
    {
        if (OnValueChanged != null)
        {
            OnValueChanged(oldValue, newValue);
        }
    }

    public override string ToString()
    {
        return (Value != null ? Value.ToString() : "null");
    }
}

随即,大家再定义三个 ViewModel,它为 View 提供了数码和作为:

 public class SetupViewModel : ViewModel
{
    public BindableProperty<string> Name = new BindableProperty<string>();
    public BindableProperty<string> Job = new BindableProperty<string>();
    public BindableProperty<int> ATK = new BindableProperty<int>();
    public BindableProperty<float> SuccessRate = new BindableProperty<float>();
    public BindableProperty<State> State = new BindableProperty<State>();
}

有了 View 与 ViewModel 之后,我们须求思考:

  • 从一个签到页面浅淡MVVM,MVVM的大旨技术。怎么着为 View 内定二个 ViewModel
  • 当 ViewModel 属性值改变时,如何订阅触发的 OnValueChanged
    事件,从而达到 View 的数码更新

依据以上两点,大家得以定义3个通用的 View,将它取名字为 UnityGuiView

public interface IView
{
    ViewModel BindingContext { get; set; }
}

public class UnityGuiView:MonoBehaviour,IView
{
    public readonly BindableProperty<ViewModel> ViewModelProperty = new BindableProperty<ViewModel>();
    public ViewModel BindingContext
    {
        get { return ViewModelProperty.Value; }
        set { ViewModelProperty.Value = value; }
    }

    protected virtual void OnBindingContextChanged(ViewModel oldViewModel, ViewModel newViewModel)
    {
    }

    public UnityGuiView()
    {
        this.ViewModelProperty.OnValueChanged += OnBindingContextChanged;
    }

}
  • 上述代码中,提供2个 BindingContext 上下文属性,类似于 WPF 中的
    DataContext。 BindingContext 属性大家无法将它视为二个简单的属性
    ,它是上述定义过的 BindableProperty 类型属性。那么当为三个 View 的
    BindingContext 内定 ViewModel 实例时,起始化时,势必会触发
    OnValueChanged 事件。

  • 在响应函数 OnBindingContextChanged 中 ,大家得以在此对 ViewModel
    中事件展开监听,从而达到多少的更新。当然那是叁个虚方法,你供给在子类
    View 中 Override。

于是修改定义过的 SetupView,继承自 UnityGuiView:

public class SetupView:UnityGuiView
{
   ...省略部分代码

   public SetupViewModel ViewModel { get { return (SetupViewModel)BindingContext; } }

   protected override void OnBindingContextChanged(ViewModel oldViewModel, ViewModel newViewModel)
    {

        base.OnBindingContextChanged(oldViewModel, newViewModel);

        SetupViewModel oldVm = oldViewModel as SetupViewModel;
        if (oldVm != null)
        {
            oldVm.Name.OnValueChanged -= NameValueChanged;
            ...
        }
        if (ViewModel!=null)
        {
            ViewModel.Name.OnValueChanged += NameValueChanged;
            ...
        }
        UpdateControls();
    }

    private void NameValueChanged(string oldvalue, string newvalue)
    {
        nameMessageText.text = newvalue.ToString();
    }
}

是因为子类 Override 了 OnBindingContextChanged 方法,故它会对 ViewModel
的属性值改变事件进行监听,当接触时,将风尚的数目同步到 UI 中。

同理,思量到双向绑定,你也能够在 View 中定义一个 OnTextBoxValueChanged
响应函数,当文本框中的数据变动时,在响应函数中就多少同步到 ViewModel
中。在那小编就不累述了。

最后,在 Unity 3D 中将 SetupView 附加到 相应的 GameObject上:

亚洲必赢官网 6

终极在摄像机上加1段脚本,很简单,传入 SetupView 对象并为其绑定
ViewModel:

public SetupView setupView;
void Start()
{
    //绑定上下文
    setupView.BindingContext=new SetupViewModel();
}
 //向客户端发出某一属性值已更改的通知。
 public interface INotifyPropertyChanged
 {
     //在更改属性值时发生。
     event PropertyChangedEventHandler PropertyChanged;
 }

      <Setter Property=”Width”  Value=”100″ />

亚洲必赢官网 7亚洲必赢官网 8亚洲必赢官网,LoginViewModel.cs的字段与品质

小结

那是1个万分简单的 MVVM 框架,也说明了在 Unity 3D 中贯彻 MVVM
设计方式的大概。
源代码托管在Github上,点击此询问

概念很粗大略,咱们能够看看那几个接口只定义了3个轩然大波性质——PropertyChanged。所以这几个PropertyChanged就是新闻的中坚了。

    </Style>

[System.Diagnostics.DebuggerStepThroughAttribute()]
public class LoginViewModel : System.ComponentModel.INotifyPropertyChanged
{
    #region 字段
    private string ValidationCodeField;

    private string GivenValidationCodeField;

    private string MessageField;

    private bool IsDoneField;

    private LoginProxy.LoginServiceClient client;
    #endregion

    #region 属性
    public User Data
    {
        get; private set;
    }

    [Required]
    [StringLength(4, MinimumLength = 4)]
    [Display(Name = "校验码", Description = "不区分大小写")]
    [RegularExpression("^[a-zA-Z0-9]*$", ErrorMessage = "只能输入字母、数字")]
    public string ValidationCode
    {
        get
        {
            return this.ValidationCodeField;
        }
        set
        {
            if ((object.ReferenceEquals(this.ValidationCodeField, value) != true))
            {
                this.ValidateProperty("ValidationCode", value);
                if (!object.Equals(value, this.GivenValidationCodeField))
                {
                    throw new NotSupportedException("请按照给定校验码输入");
                }
                this.ValidationCodeField = value;
                this.RaisePropertyChanged("ValidationCode");
            }
        }
    }
    public string GivenValidationCode
    {    ...
    }
    /// <summary>
    /// 用于代表消息,包括异常
    /// </summary>
    public string Message
    {    ... //在 setter 中 RaisePropertyChanged()
    }
    /// <summary>
    /// 用于表示登录是否成功
    /// </summary>
    public bool IsDone
    {
        ....//在 setter 中 RaisePropertyChanged()
    }
    #endregion

    #region 构造函数
    public LoginViewModel()
    {
        this.Data = new User();
    }
    #endregion
 .......

}
 

那正是说学习运用消息的方式就应运而生了,即,制造3个一连INotifyPropertyChanged接口的类,然后在类内,完结PropertyChanged就能够了。

  Style中还足以添加Template,然后放置更多的体制模板。

 

新闻的使用

二、数据绑定,能够说是MVVM的主干。界面和后台的数额交互代码,统统放置在VM(ViewModel)中,M(Model)中放置数据对象,如SQL数据库中的订单表,在Modle中正是3个指标类。V(View)是界面层。

在 ViewModel 中,把第壹品级中用到的 User 、ValidationModel 、LoginProxy.LoginServiceClient
全体组成

上边介绍消息是用来传递信息的。那么或然会有同学好奇,引用类型的目的不就能够打包传递音讯吗?为何还要用消息啊?

 
方今做了多个DataGrid的数据绑定,列中放置了TextBox、ComboBox、Button的控件,使用数据绑定驱动控件。

到了联合,并且扩大了 Message 和 IsDone
三个天性,目的在于通过 Binding 能在 UI 中彰显出 ViewModel
中的状态变化。

因为微微数据是储存在非引用类型的目的中的。比如字符串,或数字等。

亚洲必赢官网 9

亚洲必赢官网 10亚洲必赢官网 11对Message和IsDone的控制

为了让字符串、数字等数据的改动也能如引用类型一样,能够传递回给源,就供给使用新闻了。

DataGrid的Columns中利用DataGridTemplateColumn,能够停放TextBox等控件。并在TextBox中添加Text博克斯Changed事件,引用(xmlns:ie=”,

this.client.LoginCompleted += (sender, e) =>
{
    if (e.Error == null)
    {
        if (e.Result == 1)
        {
            // 登录成功
            this.HandleMessage("登录成功");
            this.IsDone = true;
        }
        else if (e.Result == 0)
        {
            // 用户名或密码错误
            this.HandleMessage("用户名或密码错误");
        }
        else if (e.Result == 4)
        {
            // 校验码失效
            this.HandleMessage("校验码失效");
        }
    }
    else
    {
        // 处理异常
        this.HandleException(e.Error);
    }
};

/// <summary>
/// 简单的消息处理
/// </summary>
/// <param name="msg"></param>
void HandleMessage(string msg)
{
    this.Message = string.Format("消息:{0}", msg);
}
/// <summary>
/// 简单的异常处理
/// </summary>
/// <param name="ex"></param>
void HandleException(Exception ex)
{
    this.Message = string.Format("异常:{0}" , ex.Message);
}

上边大家来看下音讯的根底用法。

<ie:Interaction.Trigger>

 

率先,大家采纳WPF创设一个种类,然后创设贰个页面,起名字为WindowNotify,编辑内容如下:

  <ie:EvenTrigger EventName=”TextChanged”>

再便是对UI公开了收获校验码和登录的五个异步方法

<Window x:Class="WpfApplication.WindowNotify"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WindowNotify" Height="120" Width="200">
    <Grid>
        <StackPanel>
            <TextBox Name="txtName" VerticalAlignment="Top" Height="24" ></TextBox>
            <TextBox Name="txtNameNotify" VerticalAlignment="Top"  Height="24" ></TextBox>
            <Button Click="Button_Click" Height="30" Content="查看结果"></Button>
        </StackPanel>
    </Grid>
</Window>

    <ie:InvokeCommandAction Command=”{Binding
String,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}”
CommandParameter=”String” />

亚洲必赢官网 12亚洲必赢官网 13对View公开的艺术

接下去,编辑Xaml对于的cs文件,内容如下:

 </ie:Interaction.Trigger>

#region 公开的方法
public void GenerateValidationCodeAsync()
{
    if (this.NeedInitializeClient())
    {
        this.InitializeClient();
    }
    this.client.GenerateValidationCodeAsync();
}

public void LoginAsync()
{
    if (this.NeedInitializeClient())
    {
        this.InitializeClient();
    }
    this.client.LoginAsync(this.Data, this.ValidationCode);
}
#endregion
public partial class WindowNotify : Window
{ 
    private string _KName = "Kiba518"; 
    public string KName
    {
        get { return _KName; }
        set { _KName = value; }
    }
    WindowNotifyViewModel vm;
    public WindowNotify()
    {
        InitializeComponent();
        vm = new WindowNotifyViewModel(); 
        Binding bding = new Binding();
        bding.Path = new PropertyPath("KName");
        bding.Mode = BindingMode.TwoWay; 
        bding.Source = vm; 
        txtNameNotify.SetBinding(TextBox.TextProperty, bding);  
        txtName.Text = KName;
        txtNameNotify.Text = vm.KName; 
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("[txtName:" + KName + "]     |    [txtNameNotify:" + vm.KName + "]");
    } 
}
public class WindowNotifyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _KName = "Kiba518Notify";
    public string KName
    {
        get { return _KName; }
        set
        {
            _KName = value;
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("KName"));
            }
        }
    }
}

在Button中直接能够使用Command和CommandParameter,CommandParameter中得以应用ElementName传递任何控件到VM层。当然如此就违背了MVVM的筹划初级中学,但是须要情况下,也足以如此用。如在增选了DataGrid的1行中的Button,怎样得到Button所在行的其余列的新闻呢?把DataGrid传过去就很便利了,直接接纳SelectedItem。当然也可以在V层
.cs代码中拿走后传递到VM层。

 

此地大家成立了二个ViewModel——WindowNotifyViewModel,大家让这几个VM继承INotifyPropertyChanged,然后定义了多个KName属性,并定义了PropertyChanged事件触发的职责。

在DataGrid绑定数据时,钦赐ItemsSource=“{Binding
xxx}“,VM层中选拔ObservableCollection<xxxModel>
集合,并安装OnPropertyChanged。DataGrid列中Binding对象xxModel中的属性就足以了。

 在 View 部分,Xaml
中的变化相当小,只是绑定路径变化了,

有同学只怕会咋舌,PropertyChanged事件是曾几何时被赋值的呢?别心急,请耐心往下看。

这么就足以在DataGrid中展现数据。有时候这样Binding后要么不可能显得数据,或许是Binding数据对象急需静态什么的。如ComboBox中绑定,那么些自家是设定类ComboBox类,当中有Value和Text及Guid属性,并在xxxModle(DataGrid数据源对象中)定义集合,并在集合中添加值。并且Binding时如此写(别问为怎么,也是在网上找到代码):”{Binding
xxxModel.xxxCbBox},RelativeSource={RelativeSource
Mode=FindAncestor,AncestorType=DataGrid},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}“。

如 txtUserName
的从 Text=”{Binding UserName… 变为 Text=”{Binding
Data.UserName…

ViewModel定义完毕今后,大家再看Xaml对应的cs文件。那里我们也定义了多个KName属性。然后初步化时,将cs文件的KName和VM的KName分别赋值给前台定义的四个TextBox控件。

 

 

那边用vm的KName属性赋值时,稍微有点专门,稍后再介绍。

Button的Visibility属性同样能够做Banding。

而在 cs
变分,代码明显降少了:

下一场大家运转页面,并修改八个文本框内的值。再点击查阅结果按钮。获得界面如下:

亚洲必赢官网 14亚洲必赢官网 15LoginPage.cs

亚洲必赢官网 16

public partial class LoginPage : Page
{
    LoginViewModel loginVM;

    public LoginPage()
    {
        InitializeComponent();
        this.loginVM = new LoginViewModel();
        this.loginVM.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(loginVM_PropertyChanged);
        this.Loaded+=new RoutedEventHandler(LoginPage_Loaded);
    }

    void loginVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "IsDone")
        {
            if (this.loginVM.IsDone)
            {
                // 登录成功,执行跳转
            }
        }
        else if (e.PropertyName == "Message")
        {
            // 可以在 UI 上将 Message 也和 TextBlock 等进行绑定,以显示消息
            MessageBox.Show(this.loginVM.Message);
        }
    }


    void LoginPage_Loaded(object sender, RoutedEventArgs e)
    {
        this.loginVM.GenerateValidationCodeAsync();
        this.DataContext = this.loginVM;
    }

    private void btnChangeValidationCode_Click(object sender, RoutedEventArgs e)
    {
        this.loginVM.GenerateValidationCodeAsync();
    }

    // 对 validationSummary1 进行判断的这段代码是否该移入 ViewModel 中?
    // 如果移进去了,则会造成 ViewModel 依赖于 UI,
    // 如果仅是把 validationSummary1、LayoutRoot 作为参数传递,对于复杂的UI,可能要传递多个这样的参数
    private void btnLogin_Click(object sender, RoutedEventArgs e)
    {
        if (this.validationSummary1.HasErrors)
        {
            this.validationSummary1.Focus();
            return;
        }
        else
        {
            // 扩展方法,校验各个控件的数据绑定
            this.LayoutRoot.Children.ValidateSource();
            if (this.validationSummary1.HasErrors)
            {
                this.validationSummary1.Focus();
                return;
            }
        }

        this.loginVM.LoginAsync();
    }
}

能够从图中看看,界面修改了TextBox的Text属性,WindowNotifyViewModel的KName属性对修改的值进行了联合,而WindowNotify的KName未有壹起。

此处经过 LoginViewModel.PropertyChanged
来显示 ViewModel 中的状态变化,那只是一种表示,

看达成果,我们回过来看下VM的KName的意想不到赋值方式。大家先看率先句:

假定你愿意,也得以在 ViewModel 中追加1些
event 等来促成。

Binding bding = new Binding();

 

那边的Binding是绑定的意思,那行代码很精通是用来定义1个绑定。

此处,作者拿不定主意的是 btnLogin_Click()
里面包车型大巴 Validate 代码,该不应当把这一个代码移入 ViewModel 中,

绑定是个不好驾驭的词,我们该怎么了解啊?

是或不是该让 ViewModel 重视于 View
?个人觉得 ViewModel 依然不要借助于 View 的为好。

很简单,大家得以将绑定了解为套索,既然是套索,那么就该有多个属性,1个是套头,贰个是套尾。

 

那么证明了套索之后,大家便须求为套索的索尾赋值了,即数据源的那一方。 

从职分的角度来看,笔者更偏向于把 Validation
和 Binding 统1作为是在 View 中完结的,可是那样就会在

代码里,大家因此Binding的帕特h和Source设置了索尾的数据源和数据源绑定的性质。之后我们还设置了绑定方式是双向绑定,即两边修改都会开始展览多少传递。

View
中书写一些代码(可能只怕是有艺术能在Xaml中钦点,但是自个儿还不清楚?),即便如此,在第1品级中,

设置好了套索后,大家在让TextBox控件自身转进套头里,并设置了TextBox控件绑定的属性。代码如下:

或许品尝了把 Validation 看作是 ViewModel
的天职,在 ViewModel 中追加质量,把 Validation 彻底放

txtNameNotify.SetBinding(TextBox.TextProperty, bding);  

在 ViewModel 中 —- 这样做仅是为了让
View 的代码更少。

在我们Text博克斯控件本人转进套头里的时候,会对数据源的PropertyChanged进行赋值,那样大家就贯彻了字符串数据的传导。

 

自然,那样赋值看起来相比迟钝。那么有更便捷的法子吧。

Silverlight 4.0 为 ButtonBase 控件扩张了
Command 信赖项属性,那样能够在 Xaml 中进行越多的绑定,

答案自然是:有。

更彻底的诀别 View 和 ViewModel。

MVVM的基本功运用

 

地方的代码已经落实了ViewModel,那么壹旦在那一个基础上实行优化,即可兑现最简便的MVVM的行使。

补给,还有某个,刚刚在任何的博主的小说中看出:

优化Xaml代码如下:

  View Model有以下多个部分构成

<StackPanel> 
    <TextBox Name="txtNameNotify" Text="{Binding KName}" VerticalAlignment="Top"  Height="24" ></TextBox>
    <Button Click="Button_Click" Height="30" Content="查看结果"></Button>
</StackPanel>

  一、属性:二个东西,它的品种能够是一个字符型,也能够是1个目的。完成接口INotifyPropertyChanged,那么任何UI成分绑定到那些个性,不管那特性情几时改变都能半自动和UI层交互。

优化Xaml.cs代码如下: 

  贰、集合:事物的聚集,它的花色1般是ObservableCollection,因而,任何UI成分绑定到它,不管那几个集合哪一天改变,都能够自动的与UI交互。

 public partial class WindowNotify : Window
 {  
     public WindowNotify()
     {
         InitializeComponent();
         this.DataContext = new WindowNotifyViewModel(); 

     }
     private void Button_Click(object sender, RoutedEventArgs e)
     {
         var vm = this.DataContext as WindowNotifyViewModel;
         MessageBox.Show("[txtNameNotify:" + vm.KName + "]");
     } 
 }
 public class WindowNotifyViewModel : INotifyPropertyChanged
 {
     public event PropertyChangedEventHandler PropertyChanged;
     private string _KName = "Kiba518";
     public string KName
     {
         get { return _KName; }
         set
         { 
             _KName = value;
             if (this.PropertyChanged != null)
             {
                 this.PropertyChanged(this, new PropertyChangedEventArgs("KName"));
             }
         }
     }
 }

  三、Commands:八个得以被触发的风云,并且能够传递叁个类型为Object的参数。然则前提是要兑现接口ICommand。

从地点的代码中,我们能够看到在Xaml文件中,Text属性能够应用{Binding
KName}这种简写的格局,来兑现刚才极度复杂的binding赋值。

来自于

而在Xaml.cs文件中,大家将VeiwMode赋值给了DataContext那几个数额上下文,然后,大家就看看了,前台直接动用了VM里的属性。

 

如此简单的MVVM就落到实处了。

自个儿不通晓那种描述是否合法的,要是是,那小编这一个例子中的
ViewModel 中就从不 集合 了,难道那样就无法作为 ViewModel 了?

简洁的ViewModel

对此补充的增补:博主天神一已还原发布了看法,也回复了这么些难点,在此对天神一表示感激!

在地方我们见到了ViewModel的创立和利用,但ViewMode中每个属性都要设置成如此繁复的形象,稍微有点忧伤。

 

那么,大家来用CallerMemberName继续简化那几个ViewModel。

三、MVVM模式,并使用Command

优化后的代码如下:

 

public class WindowNotifyViewModel : BaseViewModel
{ 
    private string _KName = "Kiba518";
    public string KName
    {
        get { return _KName; }
        set
        { 
            _KName = value;
            OnPropertyChanged(); 
        }
    }
}
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
    { 
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    } 
}

 

如上所示,大家定义了四个BaseViewModel,并在BaseViewModel里面定义方法OnPropertyChanged,并在内部达成事件PropertyChanged的接触定义。

最终大家经过CallerMemberName性情,在方法OnPropertyChanged里来获取触发该措施的性格的称谓。

接下来我们就兑现了,相比不难的ViewModel。

PS:CallerMemberName的用法就恍如param参数一样,只要如上所示,写进去即可。

结语

到此,音信的运用就讲完了。音讯一定是MVVM的技能骨干。学会音讯才能更好的领会MVVM。

同时学会新闻,还是能辅助大家更好的知道后天风靡的前端JS的MVVM。即使实现情势不等同,但道理是一致的。

C#语法——元组类型

C#语法——泛型的三种采纳

C#语法——await与async的正确打开药格局

C#语法——委托,架构的血流

C#语法——事件,慢慢边缘化的长兄。

我对C#的认知。


注:此文章为原创,欢迎转发,请在篇章页面分明地方给出此文链接!
若你认为那篇小说基本上能用,请点击下右下角的【推荐】,非凡多谢!
设若你觉得这篇小说对您拥有协理,这就无妨支付宝小小打赏一下吗。 

亚洲必赢官网 17

 

网站地图xml地图