The ViewModelBase class is a 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
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.
public class ViewModel : ViewModelBase {
public IEnumerable<Employee> Employees {
get { return GetProperty(() => Employees); }
private set { SetProperty(() => Employees, value); }
}
protected override void OnInitializeInDesignMode() {
base.OnInitializeInDesignMode();
Employees = new List<Employee>() {
new Employee() { Name = "Employee 1" },
};
}
protected override void OnInitializeInRuntime() {
base.OnInitializeInRuntime();
Employees = DatabaseController.GetEmployees();
}
}
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 = "Employee 1"}
}
End Sub
Protected Overrides Sub OnInitializeInRuntime()
MyBase.OnInitializeInRuntime()
Employees = DatabaseController.GetEmployees()
End Sub
End Class
Access Services registered within a View
The ViewModelBase class implements the ISupportServices interface that maintains the Services mechanism. The ViewModelBase.GetService method, which employs ISupportServices interface, allows you to access services registered in a View.
<UserControl x:Class="ViewModelBaseSample.View"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModels="clr-namespace:ViewModelBaseSample.ViewModels" ...>
<UserControl.DataContext>
<ViewModels:ViewModel/>
</UserControl.DataContext>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:MessageBoxService/>
</dxmvvm:Interaction.Behaviors>
...
</UserControl>
public class ViewModel : ViewModelBase {
public IMessageBoxService MessageBoxService { get { return GetService<IMessageBoxService>(); } }
}
Public Class ViewModel
Inherits ViewModelBase
Public ReadOnly Property MessageBoxService As IMessageBoxService
Get
Return GetService(Of IMessageBoxService)()
End Get
End Property
End Class
The following topic contains more information on how to use services in View Models inherited from the ViewModelBase class: 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 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).
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).
Create Commands without command properties
The ViewModelBase class implements the ICustomTypeDescriptor interface to provide the capability to automatically create command properties based on methods (with the Command attribute) at runtime.
The traditional approach of creating commands is to declare command properties as follows.
public class ViewModel : ViewModelBase {
public ICommand SaveCommand { get; private set; }
public ViewModel() {
SaveCommand = new DelegateCommand(Save, CanSave);
}
public void Save() {
//...
}
public bool CanSave() {
//...
}
}
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()
'...
End Sub
Public Function CanSave() As Boolean
'...
End Function
End Class
Deriving from the ViewModelBase allows you to utilize a shorter definition. Set the Command attribute for the method you wish to use as a command.
public class ViewModel : ViewModelBase {
[Command]
public void Save() {
//...
}
public bool CanSave() {
//...
}
}
Public Class ViewModel
Inherits ViewModelBase
<Command>
Public Sub Save()
'...
End Sub
Public Function CanSave() As Boolean
'...
End Function
End Class
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”.
<Button Command="{Binding SaveCommand}"/>
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.
Example
This example demonstrates how to use the ViewModelBase class for inheriting view models.
<Window x:Class="Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:View="clr-namespace:Example.View"
Title="MainWindow" Height="600" Width="800">
<Grid>
<View:MainView/>
</Grid>
</Window>
' Developer Express Code Central Example:
' How to: Use the ViewModelBase Class to Inherit View Models
'
' This example demonstrates how to use the ViewModelBase class for inheriting view
' models.
' For additional information, refer to the following topic:
' Getting
' Started with DevExpress MVVM Framework. Commands and ViewModels.
' (https://community.devexpress.com/blogs/wpf/archive/2013/08/29/getting-started-with-devexpress-mvvm-framework-commands-and-view-models.aspx)
'
' You can find sample updates and versions for different programming languages here:
' http://www.devexpress.com/example=E5169
Imports System.Windows.Controls
Namespace Example.View
Partial Public Class MainView
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
Imports System.Windows
Namespace Example
Partial Public Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
<Application x:Class="Example.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
Imports System.Windows
Namespace Example
Partial Public Class App
Inherits Application
Public Sub New()
AddHandler Startup, AddressOf OnStartup
End Sub
Private Overloads Sub OnStartup(ByVal sender As Object, ByVal e As StartupEventArgs)
MainWindow = New MainWindow()
MainWindow.Show()
End Sub
End Class
End Namespace
<UserControl x:Class="Example.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModel="clr-namespace:Example.ViewModel"
mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600">
<UserControl.DataContext>
<ViewModel:MainViewModel/>
</UserControl.DataContext>
<dxmvvm:Interaction.Behaviors>
<dx:DXMessageBoxService/>
</dxmvvm:Interaction.Behaviors>
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Vertical" Margin="10">
<TextBlock Text="Bindable Properties:" Margin="2"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="FirstName: " Margin="2" VerticalAlignment="Center"/>
<TextBox Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="2" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="LastName: " Margin="2" VerticalAlignment="Center"/>
<TextBox Text="{Binding LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="2" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="FullName: " Margin="2" VerticalAlignment="Center"/>
<TextBox Text="{Binding FullName, Mode=OneWay}" IsReadOnly="True" Margin="2" VerticalAlignment="Center"/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="10" HorizontalAlignment="Left">
<TextBox x:Name="message" Text="Hello" Width="80" HorizontalAlignment="Left"/>
<Button Content="Show Message Box" Command="{Binding ShowMessageCommand}" CommandParameter="{Binding ElementName=message, Path=Text}"
Margin="2" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
Imports DevExpress.Mvvm
Namespace Example.ViewModel
Public Class MainViewModel
Inherits ViewModelBase
#Disable Warning BC42104 ' 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 & " " & LastName
End Get
End Property
#Enable Warning BC42104 ' 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 = "FirstName in DesignMode"
LastName = "LastName in DesignMode"
End Sub
Protected Overrides Sub OnInitializeInRuntime()
MyBase.OnInitializeInRuntime()
FirstName = "FirstName"
LastName = "LastName"
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
using DevExpress.Mvvm;
namespace Example.ViewModel {
public class MainViewModel : ViewModelBase {
public string FirstName {
get { return GetProperty(() => FirstName); }
set { SetProperty(() => FirstName, value, UpdateFullName); }
}
public string LastName {
get { return GetProperty(() => LastName); }
set { SetProperty(() => LastName, value, UpdateFullName); }
}
public string FullName {
get { return FirstName + " " + LastName; }
}
void UpdateFullName() {
RaisePropertyChanged(() => FullName);
}
protected override void OnInitializeInDesignMode() {
base.OnInitializeInDesignMode();
FirstName = "FirstName in DesignMode";
LastName = "LastName in DesignMode";
}
protected override void OnInitializeInRuntime() {
base.OnInitializeInRuntime();
FirstName = "FirstName";
LastName = "LastName";
}
IMessageBoxService MessageBoxService { get { return GetService<IMessageBoxService>(); } }
public DelegateCommand<string> ShowMessageCommand { get; private set; }
void ShowMessage(string message) {
MessageBoxService.Show(message);
}
bool CanShowMessage(string message) {
return !string.IsNullOrEmpty(message);
}
public MainViewModel() {
ShowMessageCommand = new DelegateCommand<string>(ShowMessage, CanShowMessage);
}
}
}
using System.Windows;
namespace Example {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
}
}
// Developer Express Code Central Example:
// How to: Use the ViewModelBase Class to Inherit View Models
//
// This example demonstrates how to use the ViewModelBase class for inheriting view
// models.
// For additional information, refer to the following topic:
// Getting
// Started with DevExpress MVVM Framework. Commands and ViewModels.
// (https://community.devexpress.com/blogs/wpf/archive/2013/08/29/getting-started-with-devexpress-mvvm-framework-commands-and-view-models.aspx)
//
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E5169
using System.Windows.Controls;
namespace Example.View {
public partial class MainView : UserControl {
public MainView() {
InitializeComponent();
}
}
}