DevExpress MVVM Kütüphanesi ile POCO View Model Oluşturma

Model-View-ViewModel deseni WPF ve Silverlight uygulamaları yazmak için kullanılan en popüler desendir. İş uygulamalarında oldukça yararlı olan birim testleri için esnek bir mimari geliştirmeye olanak sağlar.

Geleneksel MVVM geliştirmede bağlanabilir nesneler ve komutlar için ciddi oranda View Model kodu yazılır. DevExpress MVVM kütüphanesi bu işi oldukça kolaylaştırmış durumda. Bu kütüphane sayesinde POCO sınıflarını kullanarak çok hızlı bir şekilde View Model oluşturabiliyoruz. Ücretsiz olmasına karşın oldukça zengin bir kütüphane.

Projeye GitHub üzerinden ulaşabiliyoruz. Examples klasörü altında bir çok örnek kod da mevcut.
https://github.com/DevExpress/DevExpress.Mvvm.Free

Örnek kullanımını göstermek için bir Visual Studio’da bir örnek WPF projesi oluşturdum ve aşağıdaki adımları uyguladım.

  • Düzenli olması için bu projeye Views, ViewModels ve Models klasörlerini ekledim.
    MainWindow’u Views klasörüne taşıdım.
  • MainWindow.xaml’de MainWindow.cs’de namespace’leri düzenledim.
  • App.xaml’de StartupUri’yi “Views/MainWindow” olarak değiştirdim.
  • NuGet ile “DevExpressMvvm” kütüphanesini ekledim.
  • Models altına “Customer” sınıfını ekledim.
  • ViewModels altına “MainWindowViewModel” sınıfını ekledim.
  • MainWindow.xaml’e aşağıdaki namespace’leri ekledim.
    xmlns:ViewModels="clr-namespace:DxMvvmSample.ViewModels"
    xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
    
  • MainWindow.xaml’de Window’a ViewModel’i aşağıdaki gibi bağladım.
    DataContext="{dxmvvm:ViewModelSource Type=ViewModels:MainWindowViewModel}"
    
  • View Model üzerinden MessageBox gösterebilmek için MainWindow.xaml’e aşağıdaki kodu ekledim.
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:MessageBoxService/>
    </dxmvvm:Interaction.Behaviors>
    
  • Ekranda basit bir giriş formu oluşturdum. Binding’leri ekledim.
  • PasswordBox’un Password özelliği “Dependency Property” olmadığı için orada “DependencyPropertyBehavior” kullandım.

Sonuç olarak aşağıdaki gibi Model, View ve View Model sınıfları oluştu.

Model:

namespace DxMvvmSample.Models
{
    public class Customer
    {
        public virtual string UserName { get; set; }
    }
}

View:

<Window x:Class="DxMvvmSample.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:DxMvvmSample.ViewModels" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DxMvvmSample" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen" DataContext="{dxmvvm:ViewModelSource Type=ViewModels:MainWindowViewModel}">
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:MessageBoxService/>
    </dxmvvm:Interaction.Behaviors>
    <Grid>
        <Grid Width="200" VerticalAlignment="Center" Background="AliceBlue">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="48"/>
                <RowDefinition Height="48"/>
                <RowDefinition Height="48"/>
            </Grid.RowDefinitions>
            <TextBlock Text="User Name:" VerticalAlignment="Center" Margin="3,0,3,0"/>
            <TextBox Grid.Column="1" Text="{Binding Customer.UserName}" VerticalContentAlignment="Center"/>
            <TextBlock Grid.Row="1" Text="Password:" VerticalAlignment="Center" Margin="3,0,3,0"/>
            <PasswordBox Grid.Column="1" Grid.Row="1" VerticalContentAlignment="Center">
                <dxmvvm:Interaction.Behaviors>
                    <dxmvvm:DependencyPropertyBehavior PropertyName="Password" EventName="PasswordChanged" Binding="{Binding Password, Mode=TwoWay}"/>
                </dxmvvm:Interaction.Behaviors>
            </PasswordBox>
            <Button Grid.ColumnSpan="2" Grid.Row="2" Content="Login" Command="{Binding LoginCommand}"/>
        </Grid>
    </Grid>
</Window>

View Model:

using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DxMvvmSample.Models;

namespace DxMvvmSample.ViewModels
{
    public class MainWindowViewModel
    {
        protected MainWindowViewModel()
        {
            Customer = ViewModelSource.Create(() => new Customer());
        }

        public static MainWindowViewModel Create()
        {
            return ViewModelSource.Create(() => new MainWindowViewModel());
        }

        protected virtual IMessageBoxService MessageBoxService { get { return null; } }

        public virtual string Password { get; set; }

        public virtual Customer Customer { get; set; }

        public void Login()
        {
            if (CanLogin())
            {
                MessageBoxService.ShowMessage("Welcome " + Customer.UserName + "!");
            }
            else
            {
                MessageBoxService.ShowMessage("Failed.");
            }
        }

        public bool CanLogin()
        {
            return !string.IsNullOrWhiteSpace(Customer.UserName) && !string.IsNullOrEmpty(Password);
        }
    }
}

Buradan oluşturduğum örnek projeyi indirebilirsiniz.