# ViewModelBase | WPF Controls | DevExpress Documentation

The ViewModelBase class is a [BindableBase](/WPF/17350/mvvm-framework/viewmodels/bindablebase) descendant. It inherits features of the BindableBase class (such as the GetProperty, SetProperty, and RaisePropertyChanged/RaisePropertiesChanged methods) and offers the following additional capabilities.

- Initialize properties separately for runtime and design-time modes
- Access Services registered within a View
- Use View Model parent-child relationships
- Pass data between View Models
- Create Commands without command properties
- Example

## Initialize properties separately for runtime and design-time modes

A View Model may contain a property that requires access to a database. While you are working in the Visual Studio designer, the View Model is not allowed to connect to the database. This leads to an error in the designer.

In such cases, the ViewModelBase class provides the **OnInitializeInDesignMode** and **OnInitializeInRuntime** protected virtual methods, which you can override to initialize properties for runtime and design time modes separately.

- C#
- VB.NET

<section id="tabpanel_MiXk8iSEr3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ViewModel : ViewModelBase {
    public IEnumerable&lt;Employee&gt; Employees {
        get { return GetProperty(() =&gt; Employees); }
        private set { SetProperty(() =&gt; Employees, value); }
    }
    protected override void OnInitializeInDesignMode() {
        base.OnInitializeInDesignMode();
        Employees = new List&lt;Employee&gt;() {
            new Employee() { Name = &quot;Employee 1&quot; },
        };
    }
    protected override void OnInitializeInRuntime() {
        base.OnInitializeInRuntime();
        Employees = DatabaseController.GetEmployees();
    }
}
</code></pre></section>
<section id="tabpanel_MiXk8iSEr3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ViewModel
    Inherits ViewModelBase
    Public Property Employees As IEnumerable(Of Employee)
        Get
            Return GetProperty(Function() Employees)
        End Get
        Set(value As IEnumerable(Of Employee))
            SetProperty(Function() Employees, value)
        End Set
    End Property
    Protected Overrides Sub OnInitializeInDesignMode()
        MyBase.OnInitializeInDesignMode()
        Employees = New List(Of Employee) From {
            New Employee() With {.Name = &quot;Employee 1&quot;}
        }
    End Sub
    Protected Overrides Sub OnInitializeInRuntime()
        MyBase.OnInitializeInRuntime()
        Employees = DatabaseController.GetEmployees()
    End Sub
End Class
</code></pre></section>

## Access Services registered within a View

The ViewModelBase class implements the **ISupportServices** interface that maintains the [Services](/WPF/17414/mvvm-framework/services) mechanism. The **ViewModelBase.GetService** method, which employs ISupportServices interface, allows you to access services registered in a View.

- XAML

<section id="tabpanel_MiXk8iSEr3-1_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;UserControl x:Class=&quot;ViewModelBaseSample.View&quot; 
             xmlns:dxmvvm=&quot;http://schemas.devexpress.com/winfx/2008/xaml/mvvm&quot; 
             xmlns:ViewModels=&quot;clr-namespace:ViewModelBaseSample.ViewModels&quot; ...&gt; 
    &lt;UserControl.DataContext&gt; 
        &lt;ViewModels:ViewModel/&gt; 
    &lt;/UserControl.DataContext&gt; 
    &lt;dxmvvm:Interaction.Behaviors&gt;
        &lt;dxmvvm:MessageBoxService/&gt;
    &lt;/dxmvvm:Interaction.Behaviors&gt;
    ...
&lt;/UserControl&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_MiXk8iSEr3-2_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ViewModel : ViewModelBase {
    public IMessageBoxService MessageBoxService { get { return GetService&lt;IMessageBoxService&gt;(); } }
}
</code></pre></section>
<section id="tabpanel_MiXk8iSEr3-2_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ViewModel
    Inherits ViewModelBase
    Public ReadOnly Property MessageBoxService As IMessageBoxService
        Get
            Return GetService(Of IMessageBoxService)()
        End Get
    End Property
End Class
</code></pre></section>

The following topic contains more information on how to use services in View Models inherited from the ViewModelBase class: [Services in ViewModelBase descendants](/WPF/17446/mvvm-framework/services/services-in-viewmodelbase-descendants).

## Use View Model parent-child relationships

View Models inherited from the ViewModelBase can be related to each other with a parent-child relationship. This is achieved with the **ISupportParentViewModel** interface that is implemented in the ViewModelBase class. In this case, child View Models may access [Services](/WPF/17414/mvvm-framework/services) registered in the main View Model. The following topic contains more information on how you can set the parent-child relationship and what benefits you can get using this mechanism: [ViewModel relationships (ISupportParentViewModel)](/WPF/17449/mvvm-framework/viewmodels/viewmodel-relationships-isupportparentviewmodel).

## Pass data between View Models

The ViewModelBase class implements the **ISupportParameter** interface, which can be used for passing initial data to View Models. The following documentation topic describes how this mechanism operates: [Passing data between ViewModels (ISupportParameter)](/WPF/17448/mvvm-framework/viewmodels/passing-data-between-viewmodels-isupportparameter).

## Create Commands Without Command Properties

The [ViewModelBase](/CoreLibraries/DevExpress.Mvvm.ViewModelBase) class implements the [ICustomTypeDescriptor](https://learn.microsoft.com/dotnet/api/system.componentmodel.icustomtypedescriptor) interface and can automatically create command properties based on methods (with the [Command](/CoreLibraries/DevExpress.Mvvm.DataAnnotations.CommandAttribute) attribute) at runtime.

The traditional approach of creating commands is to declare command properties as follows:

- C#
- VB.NET

<section id="tabpanel_MiXk8iSEr3-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ViewModel : ViewModelBase {
    public ICommand SaveCommand { get; private set; }
    public ViewModel() {
        SaveCommand = new DelegateCommand(Save, CanSave);
    }
    public void Save() {
        //...
    }
    public bool CanSave() {
        //...
    }
}
</code></pre></section>
<section id="tabpanel_MiXk8iSEr3-3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ViewModel
    Inherits ViewModelBase
    Dim _SaveCommand As ICommand
    Public ReadOnly Property SaveCommand As ICommand
        Get
            Return _SaveCommand
        End Get
    End Property
    Public Sub New()
        _SaveCommand = New DelegateCommand(AddressOf Save, AddressOf CanSave)
    End Sub
    Public Sub Save()
        &#39;...
    End Sub
    Public Function CanSave() As Boolean
        &#39;...
    End Function
End Class
</code></pre></section>

Deriving from the `ViewModelBase` allows you to utilize a shorter definition. Set the `Command` attribute for the method you want to use as a command:

- C#
- VB.NET

<section id="tabpanel_MiXk8iSEr3-4_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ViewModel : ViewModelBase {
    [Command]
    public void Save() {
        //...
    }
    public bool CanSave() {
        //...
    }
}
</code></pre></section>
<section id="tabpanel_MiXk8iSEr3-4_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ViewModel
    Inherits ViewModelBase
    &lt;Command&gt;
    Public Sub Save()
        &#39;...
    End Sub
    Public Function CanSave() As Boolean
        &#39;...
    End Function
End Class
</code></pre></section>

The created command considers the method named *Can[MethodName]* as a `CanExecute` statement. If your `CanExecute` method has a different name, assign it to the [CommandAttribute.CanExecuteMethodName](/CoreLibraries/DevExpress.Mvvm.DataAnnotations.CommandAttribute.CanExecuteMethodName) property:

- C#
- VB.NET

<section id="tabpanel_MiXk8iSEr3-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ViewModel : ViewModelBase {
    [Command(CanExecuteMethodName = &quot;IsSaveAllowed&quot;)]
    public void Save() {
        //...
    }
    public bool IsSaveAllowed() {
        //...
    }
}
</code></pre></section>
<section id="tabpanel_MiXk8iSEr3-5_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ViewModel
    Inherits ViewModelBase

    &lt;Command(CanExecuteMethodName:=&quot;IsSaveAllowed&quot;)&gt;
    Public Sub Save()
        &#39; ...
    End Sub

    Public Function IsSaveAllowed() As Boolean
        &#39; ...
    End Function
End Class
</code></pre></section>

The [CommandAttribute.UseCommandManager](/CoreLibraries/DevExpress.Mvvm.DataAnnotations.CommandAttribute.UseCommandManager) property specifies whether to use the manager that triggers the specified `CanExecute` method each time a user interacts with the application UI.

When the `Command` attribute is applied to a method, the corresponding command will have the name: *[MethodName]Command* where [MethodName] is the name of the target method.
For the example above, the command name will be “SaveCommand”.

- XAML

<section id="tabpanel_MiXk8iSEr3-6_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;Button Command=&quot;{Binding SaveCommand}&quot;/&gt;
</code></pre></section>

The `Command` attribute can be applied to a parameter-less method or to a method with one parameter. You can also customize the command by setting `Command` attribute properties.

The following topic contains more information about commands: [Commands](/WPF/17441/mvvm-framework/commands).

## Example

This example demonstrates how to use the **ViewModelBase** class for inheriting view models.

[View Example](https://github.com/DevExpress-Examples/wpf-mvvm-framework-use-viewmodelbase-class-to-inherit-view-models)

- MainView.xaml

<section id="tabpanel_isTqYHr3uj_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;UserControl x:Class=&quot;Example.View.MainView&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;     
    xmlns:dx=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core&quot;
    xmlns:dxmvvm=&quot;http://schemas.devexpress.com/winfx/2008/xaml/mvvm&quot;
    xmlns:ViewModel=&quot;clr-namespace:Example.ViewModel&quot;
    mc:Ignorable=&quot;d&quot; d:DesignHeight=&quot;500&quot; d:DesignWidth=&quot;600&quot;&gt;
    &lt;UserControl.DataContext&gt;
        &lt;ViewModel:MainViewModel/&gt;
    &lt;/UserControl.DataContext&gt;
    &lt;dxmvvm:Interaction.Behaviors&gt;
        &lt;dx:DXMessageBoxService/&gt;
    &lt;/dxmvvm:Interaction.Behaviors&gt;

    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt;
        &lt;StackPanel Orientation=&quot;Vertical&quot;&gt;
            &lt;StackPanel Orientation=&quot;Vertical&quot; Margin=&quot;10&quot;&gt;
                &lt;TextBlock Text=&quot;Bindable Properties:&quot; Margin=&quot;2&quot;/&gt;
                &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
                    &lt;TextBlock Text=&quot;FirstName: &quot; Margin=&quot;2&quot; VerticalAlignment=&quot;Center&quot;/&gt;
                    &lt;TextBox Text=&quot;{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}&quot; Margin=&quot;2&quot; VerticalAlignment=&quot;Center&quot;/&gt;
                &lt;/StackPanel&gt;
                &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
                    &lt;TextBlock Text=&quot;LastName: &quot; Margin=&quot;2&quot; VerticalAlignment=&quot;Center&quot;/&gt;
                    &lt;TextBox Text=&quot;{Binding LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}&quot; Margin=&quot;2&quot; VerticalAlignment=&quot;Center&quot;/&gt;
                &lt;/StackPanel&gt;
                &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
                    &lt;TextBlock Text=&quot;FullName: &quot; Margin=&quot;2&quot; VerticalAlignment=&quot;Center&quot;/&gt;
                    &lt;TextBox Text=&quot;{Binding FullName, Mode=OneWay}&quot; IsReadOnly=&quot;True&quot; Margin=&quot;2&quot; VerticalAlignment=&quot;Center&quot;/&gt;
                &lt;/StackPanel&gt;
            &lt;/StackPanel&gt;
            &lt;StackPanel Orientation=&quot;Vertical&quot; Margin=&quot;10&quot; HorizontalAlignment=&quot;Left&quot;&gt;
                &lt;TextBox x:Name=&quot;message&quot; Text=&quot;Hello&quot; Width=&quot;80&quot; HorizontalAlignment=&quot;Left&quot;/&gt;
                &lt;Button Content=&quot;Show Message Box&quot; Command=&quot;{Binding ShowMessageCommand}&quot; CommandParameter=&quot;{Binding ElementName=message, Path=Text}&quot;
                        Margin=&quot;2&quot; HorizontalAlignment=&quot;Left&quot;/&gt;
            &lt;/StackPanel&gt;
        &lt;/StackPanel&gt;

    &lt;/Grid&gt;
&lt;/UserControl&gt;
</code></pre></section>

- MainViewModel.cs
- MainViewModel.vb

<section id="tabpanel_isTqYHr3uj-1_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

namespace Example.ViewModel {
    public class MainViewModel : ViewModelBase {
        public string FirstName {
            get { return GetProperty(() =&gt; FirstName); }
            set { SetProperty(() =&gt; FirstName, value, UpdateFullName); }
        }
        public string LastName {
            get { return GetProperty(() =&gt; LastName); }
            set { SetProperty(() =&gt; LastName, value, UpdateFullName); }
        }
        public string FullName {
            get { return FirstName + &quot; &quot; + LastName; }
        }
        void UpdateFullName() {
            RaisePropertyChanged(() =&gt; FullName);
        }
        protected override void OnInitializeInDesignMode() {
            base.OnInitializeInDesignMode();
            FirstName = &quot;FirstName in DesignMode&quot;;
            LastName = &quot;LastName in DesignMode&quot;;
        }
        protected override void OnInitializeInRuntime() {
            base.OnInitializeInRuntime();
            FirstName = &quot;FirstName&quot;;
            LastName = &quot;LastName&quot;;
        }

        IMessageBoxService MessageBoxService { get { return GetService&lt;IMessageBoxService&gt;(); } }
        public DelegateCommand&lt;string&gt; ShowMessageCommand { get; private set; }
        void ShowMessage(string message) {
            MessageBoxService.Show(message);
        }
        bool CanShowMessage(string message) {
            return !string.IsNullOrEmpty(message);
        }
        public MainViewModel() {
            ShowMessageCommand = new DelegateCommand&lt;string&gt;(ShowMessage, CanShowMessage);
        }
    }
}
</code></pre></section>
<section id="tabpanel_isTqYHr3uj-1_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Namespace Example.ViewModel
    Public Class MainViewModel
        Inherits ViewModelBase

#Disable Warning BC42104 &#39; Variable is used before it has been assigned a value
        Public Property FirstName As String
            Get
                Return GetProperty(Function() FirstName)
            End Get
            Set(ByVal value As String)
                SetProperty(Function() FirstName, value, AddressOf UpdateFullName)
            End Set
        End Property
        Public Property LastName As String
            Get
                Return GetProperty(Function() LastName)
            End Get
            Set(ByVal value As String)
                SetProperty(Function() LastName, value, AddressOf UpdateFullName)
            End Set
        End Property
        Public ReadOnly Property FullName As String
            Get
                Return FirstName &amp; &quot; &quot; &amp; LastName
            End Get
        End Property
#Enable Warning BC42104 &#39; Variable is used before it has been assigned a value

        Private Sub UpdateFullName()
            RaisePropertyChanged(Function() FullName)
        End Sub
        Protected Overrides Sub OnInitializeInDesignMode()
            MyBase.OnInitializeInDesignMode()
            FirstName = &quot;FirstName in DesignMode&quot;
            LastName = &quot;LastName in DesignMode&quot;
        End Sub
        Protected Overrides Sub OnInitializeInRuntime()
            MyBase.OnInitializeInRuntime()
            FirstName = &quot;FirstName&quot;
            LastName = &quot;LastName&quot;
        End Sub

        Private ReadOnly Property MessageBoxService() As IMessageBoxService
            Get
                Return GetService(Of IMessageBoxService)()
            End Get
        End Property
        Private privateShowMessageCommand As DelegateCommand(Of String)
        Public Property ShowMessageCommand() As DelegateCommand(Of String)
            Get
                Return privateShowMessageCommand
            End Get
            Private Set(ByVal value As DelegateCommand(Of String))
                privateShowMessageCommand = value
            End Set
        End Property
        Private Sub ShowMessage(ByVal message As String)
            MessageBoxService.Show(message)
        End Sub
        Private Function CanShowMessage(ByVal message As String) As Boolean
            Return Not String.IsNullOrEmpty(message)
        End Function
        Public Sub New()
            ShowMessageCommand = New DelegateCommand(Of String)(AddressOf ShowMessage, AddressOf CanShowMessage)
        End Sub
    End Class
End Namespace
</code></pre></section>