Giter Site home page Giter Site logo

shiva's Introduction

Shiva

Shiva is a simple class library for easier implementation of ViewModels. The basic design goal of it is to be used in small projects.

The word shiva in Persian means Eloquent.

Shiva in Nuget Package Gallery

Why?

When I started using MVVM, I saw myself repeating a lot of code for each VM. I searched for existing libraries to see if they can shorten my code, but they were too complicated for me. Searching for methods that addressed shortening writing ViewModels, I ended up with dynamic view models (after reading this article). This project is a try to expand the use of dynamic objects for implementing VMs.

How to use?

Assume a model and a view like these:

Model:

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }

View:

	<StackPanel Margin="5">
		<TextBlock Text="Given Name"/>
		<TextBox Text="{Binding FirstName}"/>
		<TextBlock Text="Family Name"/>
		<TextBox Text="{Binding LastName}"/>
		<TextBlock Text="Full Name"/>
		<TextBlock Text="{Binding FullName}"/>
		<TextBlock Text="Age"/>
		<TextBox Text="{Binding Age}"/>
	</StackPanel>

Writing a ViewModel for even such a simple Model is not so straightforward. So let's see what Shiva can do for us?

Basic ViewModel

All of the magic of Shiva relies in ViewModelProxy class:

    class PersonDialogViewModel : Shiva.ViewModelProxy<Models.Person>
    {
        public PersonDialogViewModel(Models.Person p)
        {
            Model = p;
        }
    }

That's all. This VM implements ViewModelProxy and the View can be bound to it. Shiva automatically exposes all properties of the following types:

  • Enumerated types
  • Simple types (int, bool, etc)
  • string
  • DateTime, TimeSpan and DateTimeOffset

Validation

What if we want to add some validation to our ViewModel? Shiva utilizes a Configuration class in each ViewModelProxy that works fine for validation.

    class PersonDialogViewModel : Shiva.ViewModelProxy<Models.Person>
    {
        public PersonDialogViewModel(Models.Person p)
        {
            Model = p;

            Configuration.Property(() => Model.Age)
                         .Enforce(x => x > 0, "Age should be greater than zero");
        }
    }

Dependent Properties

Consider the case that we want to have a FullName property in our VM like this:

        public string FullName { get { return Model.FirstName + " " + Model.LastName; } }

We can tell Shiva that whenever FirstName or LastName properties changed, it should fire PropertyChanged event for this event, too. Again in the constructor we will have:

	   Configuration.Property(() => FullName)
	                .DependsOn(() => Model.FirstName)
	                .DependsOn(() => Model.LastName);

What to do if user canceled changes?

ViewModelProxy also implements IEditableObject that can handle cancellation. The final ViewModel is here:

    class PersonDialogViewModel : Shiva.ViewModelProxy<Models.Person>
    {
        public ICommand OkCommand { get; private set; }
        public ICommand CancelCommand { get; private set; }

        public string FullName { get { return Model.FirstName + " " + Model.LastName; } }

        public PersonDialogViewModel(Models.Person p)
        {
            Model = p;

            Configuration.Property(() => Model.Age)
                         .Enforce(x => x > 0, "Age should be greater than zero");

            Configuration.Property(() => FullName)
                         .DependsOn(() => Model.FirstName)
                         .DependsOn(() => Model.LastName);

            OkCommand = new RelayCommand(x => EndEdit());
            CancelCommand = new RelayCommand(x => CancelEdit());

            BeginEdit();
        }
    }

Wrapping Object and IList Properties

Shiva can also wrap properties of type class and IList<T> through WrapObject and WrapList methods of Configuration.

More Shiva

Although Shiva is mainly formed around ViewModelProxy, it has more:

  • You may noticed that Shiva also has a simple implementation of RelayCommand.
  • ViewModelProxy provides GetMember and SetMember methods which are the recommended way for changing value of ViewModelProxy.Model members.
  • There is a SetFieldAndNotify method as an extension for INotifyPropertyChangedEx.

License

Shiva is published under MIT license. It internally uses Dinamitey which is under Apache License.

shiva's People

Contributors

melmi avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

damian-666

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.