Intersoft ClientUI Documentation
Walkthrough: Creating Model for Contact Data

This walkthrough discusses how to create Model class that will be used in other walkthroughs that use MVVM Pattern.

This particular walkthrough steps you through the process of creating a Model class for the Contact Data.

Preparing the Project Environment

To help you quickly get started with MVVM pattern application development, ClientUI provides a number of MVVM-ready project templates that integrate to Visual Studio 2010. The basic MVVM project templates include base classes such as ModelBase.cs and ViewModelBase.cs as well as several providers to work with dialog boxes in ClientUI. Some advanced MVVM business templates include more comprehensive base classes such as ValidationViewModelBase.cs and EntityValidationViewModelBase.cs to provide built-in error validation that integrates with data annotations in the domain service.

If you use other project templates that do not have base classes mentioned above, you need to prepare these classes prior to continuing the walkthrough. This section shows how to create the ModelBase class that will be used as the base class for all model objects.

To create ModelBase class

You can skip this step if you created a new project from ClientUI MVVM-ready project templates such as Intersoft ClientUI MVVM Application project template, Intersoft ClientUI MVVM Business Application project template or Intersoft ClientUI Desktop Application.

  1. In your project, create new folder with name Models.
  2. In the Models folder, add new class under with name ModelBase.cs.
  3. Open the ModelBase.cs.
  4. In the ModelBase class, implement both INotifyPropertyChange and IDataError interface.
    The INotifyPropertyChanged is one of the fundamental interfaces in Silverlight/WPF that enables the binding engine to perform two-ways data binding, that is, changes in the model can be propagated to the target that bound to that particular model.
    The IDataErrorInfo provides built-in error validation that generally notifies an error to the binding engine.
  5. Define the basic functionality to support both  INotifyPropertyChange and IDataError interface, such as shown in the following code.

    C#

    Copy Code
    public class ModelBase : INotifyPropertyChanged, IDataErrorInfo
    {
        #region Properties
    
        private Dictionary<string, string> _errors = new Dictionary<string, string>();
    
        public virtual bool HasErrors
        {
            get
            {
                return _errors.Count > 0;
            }
        }
    
        #endregion
    
        #region Public
    
        public void SetError(string propertyName, string errorMessage)
        {
            _errors[propertyName] = errorMessage;
            this.OnPropertyChanged(propertyName);
        }
    
        #endregion
    
        #region Protected
    
        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        protected void ClearError(string propertyName)
        {
            this._errors.Remove(propertyName);
        }
    
        protected void ClearAllErrors()
        {
            List<string> properties = new List<string>();
    
            foreach (KeyValuePair<string, string> error in this._errors)
                properties.Add(error.Key);
    
            this._errors.Clear();
    
            foreach (string property in properties)
                this.OnPropertyChanged(property);
        }
    
        #endregion
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        #endregion
    
        #region IDataErrorInfo Members
    
        public string Error
        {
            get { return null; }
        }
    
        public string this[string columnName]
        {
            get
            {
                if (this._errors.ContainsKey(columnName))
                {
                    return this._errors[columnName];
                }
                return string.Empty;
            }
        }
    
        #endregion
    }

Creating the Contact Model Class

This section shows how to create the Contact model class that represents the contact data entity. To simplify the process, this walkthrough will create data source from an XML file.

You can get the XML file from: [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.Assets\Data\ContactDataSource.xml

ContactDataSource.xml
Copy Code
<?xml version="1.0" encoding="utf-8" ?>
<Customers>
    <Customer>
        <Name>Maria Larsson</Name>
        <Address>Åkergatan 24</Address>
        <Phone>1-410-918-5937</Phone>
        <Cell>1-555-123-9250</Cell>
        <Id>MARIA</Id>
        <Email>maria@contoso.com</Email>
        <Fax></Fax>
        <Blog>http://www.cpandl.com/</Blog>
        <Twitter>http://twitter.com/mlarsson</Twitter>
        <Website>http://www.contoso.com/</Website>
        <State>TX</State>
        <ZipCode>67355</ZipCode>
    </Customer>

     ....

</Customers>

Next, you need to add the XML file to your project along with some images for each contact.

To add the data file

  1. In your project, create new folder with name Data.
  2. In Data folder, insert the data source from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.Assets\Data\ContactDataSource.xml.
  3. Click on the ContactDataSource.xml file and press F4 to open the Property Window. Change the Build Action property to Resources.  

To add the resources file

  1. In your project, create new folder with name Assets.
  2. In Assets folder, create new folder with name Images.
  3. In Images folder, create new folder with name Photos .
  4. In Photos folder, copy the images from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.Assets\Images\Photos\].
    These images will be used as photo for each contact in our data source.

Next, you create the Contact model class based on the data structure specified in our source file.

To create the Contact Model class

  1. In your project, locate Models folder.
    If you do not have this folder, most likely you are using project template that does not have MVVM template ready. See the Preparing Project Environment section above before proceeding to the next step.
  2. In Models folder, add new class with name Contact.
  3. At the Contact class, inherit the ModelBase class.
    C#
    Copy Code
    public class Contact : ModelBase
    {
    }
  4. In Contact model class, create Name property by defining the backing field along with complete getter and setter in the property. You also need to call the OnPropertyChanged method after the backing field is assigned to notify the binding engine that value has been updated.
    CS
    Copy Code
    private string _name = string.Empty;
    
    public string Name
    {
        get
        {
            return this._name;
        }
    
        set
        {
            if (this._name != value)
            {
                this._name = value;
                this.ClearError("Name");
                this.OnPropertyChanged("Name");
            }
        }
    }

    Notice that it also called ClearError("Name") after the backing field is assigned. This is used to clear the error flag after user type provided with the new value for scenario where validation is enabled.
  5. Create Address, Phone, Cell, Id, Email, Fax, Blog, Twitter, WebSite, State, ZipCode and Photo properties by repeating step number 4.
    C#
    Copy Code
    private string _address = string.Empty;
    private string _phone = string.Empty;
    private string _cell = string.Empty;
    private string _id = string.Empty;
    private string _email = string.Empty;
    private string _fax = string.Empty;
    private string _blog = string.Empty;
    private string _twitter = string.Empty;
    private string _website = string.Empty;
    private string _state = string.Empty;
    private string _zipCode = string.Empty;
    private Uri _photo = null;
    
    public string Address
    {
        get
        {
            return this._address;
        }
    
        set
        {
            if (this._address != value)
            {
                this._address = value;
                this.ClearError("Address");
                this.OnPropertyChanged("Address");
            }
        }
    }
    
    public string Phone
    {
        get
        {
            return this._phone;
        }
    
        set
        {
            if (this._phone != value)
            {
                this._phone = value;
                this.OnPropertyChanged("Phone");
            }
        }
    }
    
    public string Cell
    {
        get
        {
            return this._cell;
        }
    
        set
        {
            if (this._cell != value)
            {
                this._cell = value;
                this.OnPropertyChanged("Cell");
            }
        }
    }
    
    public string Id
    {
        get
        {
            return this._id;
        }
    
        set
        {
            if (this._id != value)
            {
                this._id = value;
                this.OnPropertyChanged("Id");
            }
        }
    }
    
    public string Email
    {
        get
        {
            return this._email;
        }
    
        set
        {
            if (this._email != value)
            {
                this._email = value;
                this.OnPropertyChanged("Email");
            }
        }
    }
    
    public string Fax
    {
        get
        {
            return this._fax;
        }
    
        set
        {
            if (this._fax != value)
            {
                this._fax = value;
                this.OnPropertyChanged("Fax");
            }
        }
    }
    
    public string Blog
    {
        get
        {
            return this._blog;
        }
    
        set
        {
            if (this._blog != value)
            {
                this._blog = value;
                this.OnPropertyChanged("Blog");
            }
        }
    }
    
    public string Twitter
    {
        get
        {
            return this._twitter;
        }
    
        set
        {
            if (this._twitter != value)
            {
                this._twitter = value;
                this.OnPropertyChanged("Twitter");
            }
        }
    }
    
    public string Website
    {
        get
        {
            return this._website;
        }
    
        set
        {
            if (this._website != value)
            {
                this._website = value;
                this.OnPropertyChanged("Website");
            }
        }
    }
    
    public string State
    {
        get
        {
            return this._state;
        }
    
        set
        {
            if (this._state != value)
            {
                this._state = value;
                this.OnPropertyChanged("State");
            }
        }
    }
    
    public string ZipCode
    {
        get
        {
            return this._zipCode;
        }
    
        set
        {
            if (this._zipCode != value)
            {
                this._zipCode = value;
                this.ClearError("ZipCode");
                this.OnPropertyChanged("ZipCode");
            }
        }
    }
    
    public Uri Photo
    {
        get
        {
            return this._photo;
        }
    
        set
        {
            if (this._photo != value)
            {
                this._photo = value;
                this.OnPropertyChanged("Photo");
            }
        }
    
    }
  6. In Contact model class, create a constructor that accepts XElement as its parameter. This constructor is used to ease the data parsing process from the xml to the object model.
    C#
    Copy Code
    public Contact()
    {
    }
    
    public Contact(XElement x)
        : this()
    {
        this._id = x.Element("Id").Value.Trim();
        this._name = x.Element("Name").Value.Trim();
        this._email = x.Element("Email").Value.Trim();
    
        this._address = x.Element("Address").Value.Trim();
        this._state = x.Element("State").Value.Trim();
        this._zipCode = x.Element("ZipCode").Value.Trim();
    
        this._phone = x.Element("Phone").Value.Trim();
        this._fax = x.Element("Fax").Value.Trim();
        this._cell = x.Element("Cell").Value.Trim();
    
        this._blog = x.Element("Blog").Value.Trim();
        this._twitter = x.Element("Twitter").Value.Trim();
        this._website = x.Element("Website").Value.Trim();
    }
  7. Lastly, add the SetPhoto method to assign the photo to each Contact object.
    Notice that in the ContactDataSource.xml there are no photo data. This method will be used later in the ViewModel to assign photo to each Contact object at load data method.
    C#
    Copy Code
    public void SetPhoto(string uri)
    {
        this.Photo = new Uri("/YourApplicationProject;component/Assets/Images/Photos/" + uri + ".jpg", UriKind.RelativeOrAbsolute);
    }

 

Conclusion

In this walkthrough, you have learned how to do the following:

Complete Code Listing

This section lists the complete code used in this walkthrough.

Contact.cs

C#
Copy Code
    public class Contact : ModelBase
    {        
        #region Constructors

        public Contact()
        {
        }

        public Contact(XElement x)
            : this()
        {
            this._id = x.Element("Id").Value.Trim();
            this._name = x.Element("Name").Value.Trim();
            this._email = x.Element("Email").Value.Trim();

            this._address = x.Element("Address").Value.Trim();
            this._state = x.Element("State").Value.Trim();
            this._zipCode = x.Element("ZipCode").Value.Trim();

            this._phone = x.Element("Phone").Value.Trim();
            this._fax = x.Element("Fax").Value.Trim();
            this._cell = x.Element("Cell").Value.Trim();

            this._blog = x.Element("Blog").Value.Trim();
            this._twitter = x.Element("Twitter").Value.Trim();
            this._website = x.Element("Website").Value.Trim();
        }

        #endregion

        #region Fields

        private string _name = string.Empty;
        private string _address = string.Empty;
        private string _phone = string.Empty;
        private string _cell = string.Empty;
        private string _id = string.Empty;
        private string _email = string.Empty;
        private string _fax = string.Empty;
        private string _blog = string.Empty;
        private string _twitter = string.Empty;
        private string _website = string.Empty;
        private string _state = string.Empty;
        private string _zipCode = string.Empty;
        private Uri _photo = null;

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                return this._name;
            }

            set
            {
                if (this._name != value)
                {
                    this._name = value;
                    this.ClearError("Name");
                    this.OnPropertyChanged("Name");
                }
            }
        }

        public string Address
        {
            get
            {
                return this._address;
            }

            set
            {
                if (this._address != value)
                {
                    this._address = value;
                    this.ClearError("Address");
                    this.OnPropertyChanged("Address");
                }
            }
        }

        public string Phone
        {
            get
            {
                return this._phone;
            }

            set
            {
                if (this._phone != value)
                {
                    this._phone = value;
                    this.OnPropertyChanged("Phone");
                }
            }
        }

        public string Cell
        {
            get
            {
                return this._cell;
            }

            set
            {
                if (this._cell != value)
                {
                    this._cell = value;
                    this.OnPropertyChanged("Cell");
                }
            }
        }

        public string Id
        {
            get
            {
                return this._id;
            }

            set
            {
                if (this._id != value)
                {
                    this._id = value;
                    this.OnPropertyChanged("Id");
                }
            }
        }

        public string Email
        {
            get
            {
                return this._email;
            }

            set
            {
                if (this._email != value)
                {
                    this._email = value;
                    this.OnPropertyChanged("Email");
                }
            }
        }

        public string Fax
        {
            get
            {
                return this._fax;
            }

            set
            {
                if (this._fax != value)
                {
                    this._fax = value;
                    this.OnPropertyChanged("Fax");
                }
            }
        }

        public string Blog
        {
            get
            {
                return this._blog;
            }

            set
            {
                if (this._blog != value)
                {
                    this._blog = value;
                    this.OnPropertyChanged("Blog");
                }
            }
        }

        public string Twitter
        {
            get
            {
                return this._twitter;
            }

            set
            {
                if (this._twitter != value)
                {
                    this._twitter = value;
                    this.OnPropertyChanged("Twitter");
                }
            }
        }

        public string Website
        {
            get
            {
                return this._website;
            }

            set
            {
                if (this._website != value)
                {
                    this._website = value;
                    this.OnPropertyChanged("Website");
                }
            }
        }

        public string State
        {
            get
            {
                return this._state;
            }

            set
            {
                if (this._state != value)
                {
                    this._state = value;
                    this.OnPropertyChanged("State");
                }
            }
        }

        public string ZipCode
        {
            get
            {
                return this._zipCode;
            }

            set
            {
                if (this._zipCode != value)
                {
                    this._zipCode = value;
                    this.ClearError("ZipCode");
                    this.OnPropertyChanged("ZipCode");
                }
            }
        }

        public Uri Photo
        {
            get
            {
                return this._photo;
            }

            set
            {
                if (this._photo != value)
                {
                    this._photo = value;
                    this.OnPropertyChanged("Photo");
                }
            }

        }

        #endregion

        #region Methods

        public void SetPhoto(string uri)
        {
            this.Photo = new Uri("/YourApplicationProject;component/Assets/Images/Photos/" + uri + ".jpg", UriKind.RelativeOrAbsolute);
        }  

        #endregion

    }
See Also

Concepts

Other Resources