Back to Devexpress

DispatcherService

wpf-113861-mvvm-framework-services-predefined-set-dispatcherservice.md

latest7.7 KB
Original Source

DispatcherService

  • Apr 15, 2024
  • 3 minutes to read

The DispatcherService is an IDispatcherService implementation that allows you to perform actions in a ViewModel using the Dispatcher.

Getting Started with DispatcherService

To perform an action in a ViewModel using the Dispatcher , use the DispatcherService. Add the service to the view’s dxmvvm:Interaction.Behaviors.

xaml
<UserControl x:Class="DXSample.View.MainView"
    ...
    xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
    xmlns:vm="clr-namespace:DXSample.ViewModel"  
    DataContext="{dxmvvm:ViewModelSource Type=vm:MainViewModel}">
    ...
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:DispatcherService />
    </dxmvvm:Interaction.Behaviors>
    ...
</UserControl>

Use the following approaches to access the defined DispatcherService from your ViewModel:

To perform the required actions, use the BeginInvoke(Action) method, as shown in the code snippet below.

csharp
[POCOViewModel]
public class MainViewModel {
    protected IDispatcherService DispatcherService { get { return this.GetService<IDispatcherService>(); } }
    ...
    void CalcCore() {
        ...
        DispatcherService.BeginInvoke(() => { ... });
        ...     
    }
    ...
}

The DispatcherService includes the following properties:

csharp
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;

namespace DXSample.ViewModel {
    [POCOViewModel]
    public class MainViewModel {
        public virtual int Progress { get; protected set; }
        public virtual Brush Color { get; protected set; }
        public virtual bool IsProgress { get; protected set; }
        protected IDispatcherService DispatcherService { get { return this.GetService<IDispatcherService>(); } }
        public void Calculate() {
            IsProgress = true;
            Task.Factory.StartNew(CalcCore).ContinueWith(x => {
                DispatcherService.BeginInvoke(() => IsProgress = false);
            });
        }
        protected void OnIsProgressChanged() {
            this.RaiseCanExecuteChanged(x => x.Calculate());
        }

        public bool CanCalculate() {
            return !IsProgress;
        }
        void CalcCore() {
            for (int i = 1; i <= 100; i++) {
                DispatcherService.BeginInvoke(() => {
                    Progress = i;
                    Color = new SolidColorBrush(GetColor(i));
                });
                Thread.Sleep(TimeSpan.FromSeconds(0.1));
            }
        }
        Color GetColor(int coef) {
            return new Color() {
                R = (byte)(coef * 15),
                G = (byte)(coef * 7),
                B = (byte)(coef * 8),
                A = 255,
            };
        }
    }
}
xaml
<UserControl x:Class="DXSample.View.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
    xmlns:vm="clr-namespace:DXSample.ViewModel"
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"    
    DataContext="{dxmvvm:ViewModelSource Type=vm:MainViewModel}">
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:DispatcherService DispatcherPriority="Normal"/>
    </dxmvvm:Interaction.Behaviors>

    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"
                    Orientation="Horizontal">
            <Button Content="Cacl" Command="{Binding CalculateCommand}" Margin="10"/>
            <ProgressBar Minimum="0" Maximum="100" Value="{Binding Progress, Mode=OneWay}" Margin="10" Width="200"
                         Foreground="{Binding Color}"/>
        </StackPanel>
    </Grid>
</UserControl>
vb
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.POCO
Imports DevExpress.Mvvm.DataAnnotations
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows.Media

Namespace DXSample.ViewModel
    <POCOViewModel> _
    Public Class MainViewModel
        Private privateProgress As Integer
        Public Overridable Property Progress() As Integer
            Get
                Return privateProgress
            End Get
            Protected Set(ByVal value As Integer)
                privateProgress = value
            End Set
        End Property
        Private privateColor As Brush
        Public Overridable Property Color() As Brush
            Get
                Return privateColor
            End Get
            Protected Set(ByVal value As Brush)
                privateColor = value
            End Set
        End Property
        Private privateIsProgress As Boolean
        Public Overridable Property IsProgress() As Boolean
            Get
                Return privateIsProgress
            End Get
            Protected Set(ByVal value As Boolean)
                privateIsProgress = value
            End Set
        End Property
        Protected ReadOnly Property DispatcherService() As IDispatcherService
            Get
                Return Me.GetService(Of IDispatcherService)()
            End Get
        End Property
        Public Sub Calculate()
            IsProgress = True
            Task.Factory.StartNew(AddressOf CalcCore).ContinueWith(Sub(x) DispatcherService.BeginInvoke(Sub() IsProgress = False))
        End Sub
        Protected Sub OnIsProgressChanged()
            Me.RaiseCanExecuteChanged(Sub(x) x.Calculate())
        End Sub

        Public Function CanCalculate() As Boolean
            Return Not IsProgress
        End Function
        Private Sub CalcCore()
            For i As Integer = 1 To 100
                DispatcherService.BeginInvoke(Sub()
                    Progress = i
                    Color = New SolidColorBrush(GetColor(i))
                End Sub)
                Thread.Sleep(TimeSpan.FromSeconds(0.1))
            Next i
        End Sub
        Private Function GetColor(ByVal coef As Integer) As Color
            Return New Color() With {.R = CByte(coef * 15), .G = CByte(coef * 7), .B = CByte(coef * 8), .A = 255}
        End Function
    End Class
End Namespace