威尼斯人线上娱乐

从四个记名页面浅淡MVVM,MVVM学习心德

4 4月 , 2019  

在C#中国国投息有四个针对,3个针对Message,叁个针对INotify。那里主要讲INotify。

接触MVVM接近1段时间了,有有个别知晓,写下去。

威尼斯人线上娱乐 1

初识 MVVM

聊到 MVVM 设计方式,可能首先影像你会想到
WPF/Sliverlight,他们提供了的多少绑定(Data
Binding),命令(Command)等效用,那让 MVVM 形式获得很好的落到实处。
MVVM 设计情势顾名思义,通过分离关心点,各司其职。通过 Data Binding
可达到多少的双向绑定,而下令 Command 更是将守旧的 Code Behind 事件独立到
ViewModel 中。

威尼斯人线上娱乐 2

INotify也有人称之为[通知],不管叫消息依旧公告,都以3个情趣,就是传递新闻。

前边是做winform的,工作须要,学习wpf。优缺点就绝不说类,网上一大堆。作者自个儿精晓的话,有上边几点:

如上海体育场合,扩大了1个 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
相应的品质中。

音信的概念

1、首先是界面包车型大巴xmal和界面分离:wpf也同样援助拖拉控件,不过利用wpf的人,都是为在xmal中写控件更屌一点。并且能够动用静态资源(Window。Resources)设置每三个控件的体裁(Style),统1界面风格更有益。Style中的TargetType钦定属于某一类控件,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 抽象成单身的二个个 View,将面向 Component 开发转换为面向 View
开发,每贰个 View 都有独立的 ViewModel 进行田管,如下所示:

威尼斯人线上娱乐 4

是因为 Unity 3D 未曾 XAML,也平昔不 Data Binding 技术,故只还好抽象出来的
View 中去落到实处类似于 WPF 的 Data Binding,Converter,Command 等。

从四个记名页面浅淡MVVM,MVVM学习心德。值得注意的是,MVP 设计格局中数据的绑定是由此将具体的 View 实例传递到
Presenter 中完毕的,而 MVVM 是以多少变动吸引的风浪中完成多少更新的。

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

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

上边是以此 ViewModel
的部分代码: 

MVVM 设计方式在 Unity 3D 中的设计与落到实处

再回想一下 WPF 中 ViewModel 的写法。 ViewModel 提供了 View
须求的多寡,并且 ViewModel 达成 INotifyPropertyChanged 接口
,当数码变动时,触发了 PropertyChanged
事件,由于控件也监听了此事件,在事件的响应函数里完成多少的换代。

叩问了后来,大家要思索怎么样在 Unity 3D
中去落实它。若是我们须要实现如下的2个效应,并且是使用 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;
}

可以见见,那是3个很简单的 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 之后,大家须求考虑:

  • 怎样为 View 钦赐二个 ViewModel
  • 当 ViewModel 属性值改变时,怎样订阅触发的 OnValueChanged
    事件,从而达到 View 的数码更新

传闻上述两点,大家可以定义1个通用的 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;
    }

}
  • 上述代码中,提供一个 BindingContext 上下文属性,类似于 WPF 中的
    DataContext。 BindingContext 属性大家不能够将它视为一个差不离的属性
    ,它是上述定义过的 BindableProperty 类型属性。那么当为二个 View 的
    BindingContext 钦点 ViewModel 实例时,伊始化时,势必会触发
    OnValueChanged 事件。

  • 在响应函数 OnBindingContextChanged 中 ,我们得以在此对 ViewModel
    中事件进行监听,从而达到多少的更新。当然那是2个虚方法,你需求在子类
    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威尼斯人线上娱乐 8LoginViewModel.cs的字段与性子

小结

这是三个非常简单的 MVVM 框架,也印证了在 Unity 3D 中贯彻 MVVM
设计格局的恐怕。
源代码托管在Github上,点击此询问

概念很简单,大家能够看来那么些接口只定义了一个轩然大波性质——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中即是三个目的类。V(View)是界面层。

在 ViewModel 中,把第2等级中用到的 User 、ValidationModel 、LoginProxy.LoginServiceClient
全体结合

地点介绍音信是用来传递音讯的。那么大概会有同学好奇,引用类型的指标不就足以打包传递音讯吗?为何还要用新闻啊?

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

到了壹块儿,并且增添了 Message 和 IsDone
四个脾性,意在通过 Binding 能在 UI 中显示出 ViewModel
中的状态变化。

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

威尼斯人线上娱乐 9

威尼斯人线上娱乐 10威尼斯人线上娱乐 11对Message和IsDone的控制

为了让字符串、数字等数据的修改也能如引用类型一样,能够传递回给源,就要求选用音讯了。

DataGrid的Columns中央银行使DataGridTemplateColumn,能够放置TextBox等控件。并在TextBox中添加TextBoxChanged事件,引用(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.xxxCb博克斯},RelativeSource={RelativeSource
Mode=FindAncestor,AncestorType=DataGrid},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}“。

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

ViewModel定义完结未来,大家再看Xaml对应的cs文件。那里大家也定义了2个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 中加进部分
event 等来落实。

Binding bding = new Binding();

 

那里的Binding是绑定的意趣,那行代码很扎眼是用来定义一个绑定。

此处,小编拿不定主意的是 btnLogin_Click()
里面的 Validate 代码,该不应当把那几个代码移入 ViewModel 中,

绑定是个不佳精晓的词,大家该怎么通晓呢?

是还是不是该让 ViewModel 依赖于 View
?个人觉得 ViewModel 依旧不要借助于 View 的为好。

很简短,我们得以将绑定精通为套索,既然是套索,那么就该有八个属性,一个是套头,多个是套尾。

 

威尼斯人线上娱乐,那么证明了套索之后,我们便必要为套索的索尾赋值了,即数据源的这一方。 

从职务的角度来看,小编更偏向于把 Validation
和 Binding 统1作为是在 View 中贯彻的,不过这么就会在

代码里,大家通过Binding的Path和Source设置了索尾的数据源和数据源绑定的性质。之后我们还设置了绑定形式是双向绑定,即两方修改都会开始展览数量传递。

View
中书写一些代码(或许恐怕是有主意能在Xaml中钦命,不过小编还不亮堂?),即便如此,在第二等级中,

设置好了套索后,大家在让TextBox控件本人转进套头里,并安装了TextBox控件绑定的品质。代码如下:

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

txtNameNotify.SetBinding(TextBox.TextProperty, bding);  

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

在我们TextBox控件本人转进套头里的时候,会对数据源的PropertyChanged举办赋值,那样大家就达成了字符串数据的传导。

 

理所当然,那样赋值看起来相比较愚钝。那么有更省心的章程吗。

Silverlight 四.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、属性:二个东西,它的种类能够是1个字符型,也足以是二个对象。完成接口INotifyPropertyChanged,那么任何UI成分绑定到那性格格,不管这一个天性哪天改变都能自动和UI层交互。

优化Xaml.cs代码如下: 

  贰、集合:事物的集纳,它的品类一般是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:3个得以被触发的轩然大波,并且能够传递3个品种为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));
        }
    } 
}

 

如上所示,我们定义了2个BaseViewModel,并在BaseViewModel里面定义方法OnPropertyChanged,并在中间落成事件PropertyChanged的触发定义。

终极大家经过CallerMemberName个性,在方法OnPropertyChanged里来获取触发该办法的习性的称呼。

下一场我们就完毕了,相比简单的ViewModel。

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

结语

到此,新闻的使用就讲完了。消息一定是MVVM的技能大旨。学会消息才能更好的通晓MVVM。

再者学会音信,还是能扶助我们更好的知道前日风靡的前端JS的MVVM。就算达成格局区别,但道理是一致的。

C#语法——元组类型

C#语法——泛型的多样行使

C#语法——await与async的不利打开药格局

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

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

我对C#的认知。


注:此文章为原创,欢迎转发,请在篇章页面显然地点给出此文链接!
若你认为那篇小说还能够,请点击下右下角的【推荐】,分外感激!
若果您觉得那篇小说对您拥有辅助,这就不要紧支付宝小小打赏一下吗。 

威尼斯人线上娱乐 17

 


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图