WPF learning 07: Data Binding of MVVM preparation knowledge, wpfmvvm

Source: Internet
Author: User

WPF learning 07: Data Binding of MVVM preparation knowledge, wpfmvvm

MVVM is a mode, while WPF's data binding mechanism is a function set built in WPF, which is irrelevant to the two.

However, with the help of various built-in functional sets of WPF, such as data binding, commands, and data templates, We can efficiently implement MVVM on WPF. Therefore, we need to understand the various MVVM-related WPF built-in feature sets to learn and practice MVVM on a solid basis.

This article is a follow-up of WPF 03: Element Binding. It will show three key points for data Binding: DataContext INotifyPropertyChanged IValueConverter

 

MVVM Introduction

MVVM divides the User Interface into three parts: View, Model, and View Model.

The three parts are divided as follows:

View: interface code and complete data visualization.

Model: A series of classes that we interact with the business layer.

View Model: 1. Convert the part to be displayed in the Model to View-friendly data. 2. Manage the interaction between views.

As shown in the dependency relationship, V depends on the VM, and vice versa. The VM depends on M, and vice versa.

After understanding data binding, commands, and data templates, we will return to explain MVVM again.

DataContext

In WPF learning 03: Element Binding, we only studied how to implement data Binding between controls. If ElementName is not specified, Binding will be neither set between Source nor RelativeSource, first-level query for DataContext until it is found.

Example:

<StackPanel HorizontalAlignment = "Center" TextBlock. Foreground = "# 019AFF" DataContext = "{x: Static Colors. White}"> <! -- Specify Path, an attribute of the bound object --> <TextBlock Text = "{Binding Path = R}"> </TextBlock> <TextBlock Text = "{Binding Path = G}"> </TextBlock> <TextBlock Text = "{Binding Path = B}"> </TextBlock> <! -- Bind the entire object without specifying the Path --> <TextBlock Text = "{Binding}"> </TextBlock> </StackPanel>

In common cases, we set DataContext to the top-level element, which is generally a Window.

We can configure DataContext in the background code:

public class Person{    private Int32 _age;            public Int32 Age     {        get { return _age; }        set { _age = value; }    }    private String _name;    public String Name    {        get { return _name; }        set { _name = value; }    }}private void Window_Loaded(object sender, RoutedEventArgs e){    person = new Person() { Name = "Kenny", Age = 30 };    this.DataContext = person;}private void Button_Click(object sender, RoutedEventArgs e){    person.Name = "John Locke";    person.Age = 40;}

Changes made in XAML:

<StackPanel HorizontalAlignment="Center" TextBlock.Foreground="#019AFF">    <TextBlock Text="{Binding Path=Name}"></TextBlock>    <TextBlock Text="{Binding Path=Age}"></TextBlock>    <Button Click="Button_Click">Click me</Button></StackPanel>

The effect is as follows:

We can see that the expected value is indeed displayed, but if you click the button, you will not see any changes. Next we will explain the cause and solution.

INotifyPropertyChanged

In the built-in data binding mechanism of WPF, Dependency Property can establish data binding relationships without any additional configuration. All the attributes of self-built WPF controls are packaged by the traditional. Net attributes.

If we want to set the data binding source as the property of our Defined Object and this property is not a Dependency Property, we only need to implement the INotifyPropertyChanged interface, the PropertyChanged event is called when the corresponding attribute changes to notify the target element.

We will make the following changes to the background code:

public class Person : INotifyPropertyChanged{    public event PropertyChangedEventHandler PropertyChanged;
    private Int32 _age;        public Int32 Age     {        get { return _age; }        set {             _age = value;            if (PropertyChanged != null)                PropertyChanged.Invoke(this,new PropertyChangedEventArgs("Age"));        }    }    private String _name;    public String Name    {        get { return _name; }        set {            _name = value;            if (PropertyChanged != null)                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));        }    }}

The effect is as follows:

IValueConverter

In some special cases, the source and target attributes cannot be connected and need to be converted. In this case, ValueConverter must be used. For example:

Data Binding is performed based on age, and the text is displayed in the same color. effect:

XAML code:

<TextBlock Text="{Binding Path=Name}"></TextBlock><TextBlock Name="AgeTextBlock" Text="{Binding Path=Age}"><TextBlock.Foreground>        <Binding Path="Age">            <Binding.Converter>                <local:TextBlockColorValueConverter></local:TextBlockColorValueConverter>            </Binding.Converter>        </Binding></TextBlock.Foreground></TextBlock>
Background code:
[ValueConversion (typeof (Boolean), typeof (Int32)] public class TextBlockColorValueConverter: IValueConverter {public object Convert (object value, Type targetType, object parameter, System. globalization. cultureInfo culture) {if (int) value <18) return new SolidColorBrush (Colors. violet); else return new SolidColorBrush (Colors. red);} // if no data is returned from the target, null public object ConvertBack (object value, Type targetType, object parameter, System. globalization. cultureInfo culture) {return null ;}}
Data Binding background code implementation

Previously, data binding was implemented using XAML. Here we provide the background code to implement data binding. The following example is implemented:

First, place a Name on the two controls and remove all the previously bound code:

<TextBlock Name="NameTextBlock"></TextBlock><TextBlock Name="AgeTextBlock"></TextBlock>

Background code:

var bind = new Binding("Name"){    Source = person,};NameTextBlock.SetBinding(TextBlock.TextProperty, bind);bind = new Binding("Age"){    Source = person,};AgeTextBlock.SetBinding(TextBlock.TextProperty, bind);bind = new Binding("Age"){    Source = person,    Converter = new TextBlockColorValueConverter()};AgeTextBlock.SetBinding(TextBlock.ForegroundProperty, bind);
The effect is the same as before.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.