威尼斯人线上娱乐

格局的统筹和实施,MVVM的大旨本事

2 5月 , 2019  

在C#中国国投息有多少个针对,三个针对Message,三个对准INotify。这里根本讲INotify。

接触MVVM接近1段时间了,有少数领略,写下来。

威尼斯人线上娱乐 1

初识 MVVM

谈起 MVVM 设计方式,大概首先影象你会想到
WPF/Sliverlight,他们提供了的数量绑定(Data
Binding),命令(Command)等作用,那让 MVVM 方式得到很好的兑现。
MVVM 设计格局顾名思义,通过分离关注点,各司其职。通过 Data Binding
可到达数据的双向绑定,而下令 Command 更是将古板的 Code Behind 事件独立到
ViewModel 中。

威尼斯人线上娱乐 2

INotify也有人称之为[通知],不管叫音信还是公告,都以一个意味,就是传递音讯。

事先是做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),统一分界面风格更便宜。Style中的TargetType钦点属于某一类控件,Setter钦命属性(Property)和Value。

2个 UI 对应2个 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 设计格局大旨便是,通过定义1个 View,将 UI
抽象出来,它不用关注数据的切实可行来源,也不用关怀点击按键之后业务逻辑的兑现,它只关怀UI 交互。那正是超人的分离关怀点。

实则那正是自身明天想讲的焦点,既然 Unity 3D
平素不提供数据绑定,那么大家也得以参照从前 MVP 的宏图意见:

将 UI 抽象成独立的3个个 View,将面向 Component 开辟转变为面向 View
开荒,每叁个 View 都有单独的 ViewModel 举办政管理制,如下所示:

威尼斯人线上娱乐 4

出于 Unity 3D 未有 XAML,也尚未 Data Binding 才干,故只可以在空虚出来的
View 中去落到实处类似于 WPF 的 Data Binding,Converter,Command 等。

值得注意的是,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
中去落到实处它。若是大家供给做到如下的二个功用,并且是利用 MVVM
设计观念贯彻:

威尼斯人线上娱乐 5.gif)

先是,大家要定义二个 View,这几个 View 是对 UI
元素的1个虚无,到底要抽象哪些 UI
成分呢?就以此例子来说,Input菲尔德,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 之后,大家须要思念:

  • 怎样为 View 钦赐三个 ViewModel
  • 当 ViewModel 属性值更换时,怎么着订阅触发的 OnValueChanged
    事件,从而达到 View 的数额更新

依附上述两点,大家得以定义三个通用的 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 类型属性。那么当为3个 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 中定义3个 OnTextBoxValueChanged
响应函数,当文本框中的数据变动时,在响应函数中就多少同步到 ViewModel
中。在这作者就不累述了。

格局的统筹和实施,MVVM的大旨本事。最后,在 Unity 3D 中将 SetupView 附加到 相应的 GameObject上:

威尼斯人线上娱乐 6

末尾在录像机上加一段脚本,很简短,传入 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的字段与品质

小结

那是3个分外简单的 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
 .......

}
 

那就是说学习使用消息的主意就出现了,即,创制1个接续INotifyPropertyChanged接口的类,然后在类内,完成PropertyChanged就能够了。

  Style中还足以增多Template,然后放置越来越多的体裁模板。

 

音信的利用

二、数据绑定,能够说是MVVM的大旨。分界面和后台的数据交互代码,统统放置在VM(ViewModel)中,M(Model)中放置数据对象,如SQL数据库中的订单表,在Modle中就是贰个对象类。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成立3个品种,然后创设2个页面,起名字为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层。

 

这里大家创设了3个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文件。这里我们也定义了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 中的状态变化,那只是1种表示,

看完成果,我们回过来看下VM的KName的出人意料赋值情势。我们先看率先句:

假如你愿意,也得以在 ViewModel 中加进一些
event 等来落到实处。

Binding bding = new Binding();

 

那边的Binding是绑定的乐趣,那行代码很显著是用来定义一个绑定。

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

绑定是个倒霉明白的词,大家该怎么通晓呢?

是还是不是该让 ViewModel 重视于 View
?个人以为 ViewModel 照旧不要借助于 View 的为好。

很简短,大家得以将绑定明白为套索,既然是套索,那么就该有四个属性,贰个是套头,1个是套尾。

 

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

从任务的角度来看,笔者更偏向于把 Validation
和 Binding 统1作为是在 View 中贯彻的,可是这么就可以在

代码里,咱们因此Binding的Path和Source设置了索尾的数据源和数据源绑定的性质。之后大家还设置了绑定情势是双向绑定,即两边修改都会开始展览数据传递。

View
中书写一些代码(恐怕可能是有法子能在Xaml中钦定,可是自个儿还不精通?),就算如此,在第1阶段中,

安装好了套索后,大家在让Text博克斯控件自个儿转进套头里,并安装了TextBox控件绑定的品质。代码如下:

依然品尝了把 Validation 看作是 ViewModel
的职责,在 ViewModel 中追加质量,把 Validation 深透放

txtNameNotify.SetBinding(TextBox.TextProperty, bding);  

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

在大家Text博克斯控件自个儿转进套头里的时候,会对数据源的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、属性:3个事物,它的项目能够是三个字符型,也能够是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:二个足以被触发的事件,并且能够传递三个档期的顺序为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地图