Back to Devexpress

SaveFileDialogService

wpf-114760-mvvm-framework-services-predefined-set-savefiledialogservice.md

latest14.9 KB
Original Source

SaveFileDialogService

  • Jul 11, 2021
  • 6 minutes to read

The SaveFileDialogService is an ISaveFileDialogService implementation that allows you to save data of a ViewModel to a file by using the standard dialog box.

To use the SaveFileDialogService , attach it to a View as described in Quick Actions.

xaml
<UserControl x:Class="FileDialogServicesSample.Views.FileDialogsView"
    ...
    xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm">
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:SaveFileDialogService />
    </dxmvvm:Interaction.Behaviors>
</UserControl>

Next, access the attached service and use the service’s ISaveFileDialogService.ShowDialog method to display a dialog box.

csharp
[POCOViewModel]
public class FileDialogsViewModel {

    protected ISaveFileDialogService SaveFileDialogService { get { return this.GetService<ISaveFileDialogService>(); } }
    ...
    public void Save() {
        ...
        if (SaveFileDialogService.ShowDialog()) {
            ...
        }
    }
}
vb
<POCOViewModel> _
Public Class FileDialogsViewModel
    Protected ReadOnly Property SaveFileDialogService() As ISaveFileDialogService
        Get
            Return Me.GetService(Of ISaveFileDialogService)()
        End Get
    End Property
    ...
    Public Sub Save()
        ...
        If SaveFileDialogService.ShowDialog() Then
            ...
        End If
    End Sub
End Class

A description on how to obtain a service from a View Model is available here: Services in POCO objects and Services in ViewModelBase descendants.

Then, use the FileInfoWrapper object that is stored in the ISaveFileDialogService.File property to save your data. By default, the SaveFileDialogService uses values of DefaultFileName and SaveFileDialogService.DefaultExt properties to name the file that will be used as the ViewModel’s data storage. However, an end-user can specify the file name manually by using the corresponding dialog box fields.

Note

The SaveFileDialogService uses its own FileInfoWrapper class implementing the IFileInfo interface to represent the selected file(s). This class provides the capabilities of the standard FileInfo to work with FileStream objects.

Example

View Example: OpenFileDialogService and SaveFileDialogService

xaml
<UserControl 
    x:Class="FileDialogServicesSample.Views.FileDialogsView"
    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:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"           
    xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars" 
    xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"  
    xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
    xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" 
    xmlns:ViewModels="clr-namespace:FileDialogServicesSample.ViewModels"
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <ViewModels:FileDialogsViewModel/>
    </UserControl.DataContext>

    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:OpenFileDialogService Title="{Binding Title}"/>
        <dxmvvm:SaveFileDialogService Title="{Binding Title}"/>
    </dxmvvm:Interaction.Behaviors>
    <DockPanel>
        <dxr:RibbonControl 
            DockPanel.Dock="Top" 
            ShowApplicationButton="False" 
            ToolbarShowMode="Hide" 
            RibbonTitleBarVisibility="Collapsed">
            <dxr:RibbonDefaultPageCategory Caption="Default Category">
                <dxr:RibbonPage Caption="File">
                    <dxr:RibbonPageGroup Caption="Actions">
                        <dxb:BarButtonItem 
                            Content="Open"
                            Command="{Binding OpenCommand}" 
                            Glyph="{dx:DXImage Image=Open_16x16.png}" 
                            LargeGlyph="{dx:DXImage Image=Open2_32x32.png}" 
                            RibbonStyle="Large"/>
                        <dxb:BarButtonItem 
                            Content="Save" 
                            Command="{Binding SaveCommand}" 
                            Glyph="{dx:DXImage Image=Save_16x16.png}" 
                            LargeGlyph="{dx:DXImage Image=Save_32x32.png}" 
                            RibbonStyle="Large"/>
                    </dxr:RibbonPageGroup>
                    <dxr:RibbonPageGroup Caption="Settings">
                        <dxb:BarEditItem Content="Title" EditValue="{Binding Title}">
                            <dxb:BarEditItem.EditSettings>
                                <dxe:TextEditSettings/>
                            </dxb:BarEditItem.EditSettings>
                        </dxb:BarEditItem>
                        <dxb:BarEditItem Content="Filter" EditValue="{Binding Filter}">
                            <dxb:BarEditItem.EditSettings>
                                <dxe:TextEditSettings/>
                            </dxb:BarEditItem.EditSettings>
                        </dxb:BarEditItem>
                        <dxb:BarEditItem Content="Filter Index" EditValue="{Binding FilterIndex}">
                            <dxb:BarEditItem.EditSettings>
                                <dxe:TextEditSettings/>
                            </dxb:BarEditItem.EditSettings>
                        </dxb:BarEditItem>
                    </dxr:RibbonPageGroup>
                </dxr:RibbonPage>
            </dxr:RibbonDefaultPageCategory>
        </dxr:RibbonControl>
        <dxr:RibbonStatusBarControl DockPanel.Dock="Bottom">
            <dxr:RibbonStatusBarControl.RightItems>
                <dxb:BarStaticItem Content="{Binding DialogResult}">
                    <dxb:BarStaticItem.ContentTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="Dialog Result: "/>
                                <TextBlock Text="{Binding}"/>
                            </StackPanel>
                        </DataTemplate>
                    </dxb:BarStaticItem.ContentTemplate>
                </dxb:BarStaticItem>
            </dxr:RibbonStatusBarControl.RightItems>
        </dxr:RibbonStatusBarControl>
        <TextBox 
            Text="{Binding FileBody, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
            AcceptsReturn="True" 
            TextWrapping="Wrap"/>
    </DockPanel>
</UserControl>
vb
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.DataAnnotations
Imports System.IO
Imports System.Linq

Namespace FileDialogServicesSample.ViewModels

    Public Class FileDialogsViewModel
        Inherits ViewModelBase

'#Region "Common properties"
        Public Property Filter As String
            Get
                Return GetValue(Of String)()
            End Get

            Set(ByVal value As String)
                SetValue(value)
            End Set
        End Property

        Public Property FilterIndex As Integer
            Get
                Return GetValue(Of Integer)()
            End Get

            Set(ByVal value As Integer)
                SetValue(value)
            End Set
        End Property

        Public Property Title As String
            Get
                Return GetValue(Of String)()
            End Get

            Set(ByVal value As String)
                SetValue(value)
            End Set
        End Property

        Public Property DialogResult As Boolean
            Get
                Return GetValue(Of Boolean)()
            End Get

            Protected Set(ByVal value As Boolean)
                SetValue(value)
            End Set
        End Property

        Public Property ResultFileName As String
            Get
                Return GetValue(Of String)()
            End Get

            Protected Set(ByVal value As String)
                SetValue(value)
            End Set
        End Property

        Public Property FileBody As String
            Get
                Return GetValue(Of String)()
            End Get

            Set(ByVal value As String)
                SetValue(value)
            End Set
        End Property

'#End Region
'#Region "SaveFileDialogService specific properties"
        Public Property DefaultExt As String
            Get
                Return GetValue(Of String)()
            End Get

            Set(ByVal value As String)
                SetValue(value)
            End Set
        End Property

        Public Property DefaultFileName As String
            Get
                Return GetValue(Of String)()
            End Get

            Set(ByVal value As String)
                SetValue(value)
            End Set
        End Property

        Public Property OverwritePrompt As Boolean
            Get
                Return GetValue(Of Boolean)()
            End Get

            Set(ByVal value As Boolean)
                SetValue(value)
            End Set
        End Property

'#End Region
        Protected ReadOnly Property SaveFileDialogService As ISaveFileDialogService
            Get
                Return GetService(Of ISaveFileDialogService)()
            End Get
        End Property

        Protected ReadOnly Property OpenFileDialogService As IOpenFileDialogService
            Get
                Return GetService(Of IOpenFileDialogService)()
            End Get
        End Property

        Public Sub New()
            Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*"
            FilterIndex = 1
            Title = "Custom Dialog Title"
            DefaultExt = "txt"
            DefaultFileName = "Document1"
            OverwritePrompt = True
        End Sub

        <Command>
        Public Sub Open()
            OpenFileDialogService.Filter = Filter
            OpenFileDialogService.FilterIndex = FilterIndex
            DialogResult = OpenFileDialogService.ShowDialog()
            If Not DialogResult Then
                ResultFileName = String.Empty
            Else
                Dim file As IFileInfo = OpenFileDialogService.Files.First()
                ResultFileName = file.Name
                Using stream = file.OpenText()
                    FileBody = stream.ReadToEnd()
                End Using
            End If
        End Sub

        <Command>
        Public Sub Save()
            SaveFileDialogService.DefaultExt = DefaultExt
            SaveFileDialogService.DefaultFileName = DefaultFileName
            SaveFileDialogService.Filter = Filter
            SaveFileDialogService.FilterIndex = FilterIndex
            DialogResult = SaveFileDialogService.ShowDialog()
            If Not DialogResult Then
                ResultFileName = String.Empty
            Else
                Using stream = New StreamWriter(SaveFileDialogService.OpenFile())
                    stream.Write(FileBody)
                End Using
            End If
        End Sub
    End Class
End Namespace
csharp
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using System.IO;
using System.Linq;

namespace FileDialogServicesSample.ViewModels {
    public class FileDialogsViewModel : ViewModelBase {
        #region Common properties
        public string Filter { get { return GetValue<string>(); } set { SetValue(value); } }
        public int FilterIndex { get { return GetValue<int>(); } set { SetValue(value); } }
        public string Title { get { return GetValue<string>(); } set { SetValue(value); } }
        public bool DialogResult { get { return GetValue<bool>(); } protected set { SetValue(value); } }
        public string ResultFileName { get { return GetValue<string>(); } protected set { SetValue(value); } }
        public string FileBody { get { return GetValue<string>(); } set { SetValue(value); } }
        #endregion

        #region SaveFileDialogService specific properties
        public string DefaultExt { get { return GetValue<string>(); } set { SetValue(value); } }
        public string DefaultFileName { get { return GetValue<string>(); } set { SetValue(value); } }
        public bool OverwritePrompt { get { return GetValue<bool>(); } set { SetValue(value); } }
        #endregion

        protected ISaveFileDialogService SaveFileDialogService { get { return GetService<ISaveFileDialogService>(); } }
        protected IOpenFileDialogService OpenFileDialogService { get { return GetService<IOpenFileDialogService>(); } }

        public FileDialogsViewModel() {
            Filter = "Text Files (.txt)|*.txt|All Files (*.*)|*.*";
            FilterIndex = 1;
            Title = "Custom Dialog Title";
            DefaultExt = "txt";
            DefaultFileName = "Document1";
            OverwritePrompt = true;
        }
        [Command]
        public void Open() {
            OpenFileDialogService.Filter = Filter;
            OpenFileDialogService.FilterIndex = FilterIndex;
            DialogResult = OpenFileDialogService.ShowDialog();
            if (!DialogResult) {
                ResultFileName = string.Empty;
            } else {
                IFileInfo file = OpenFileDialogService.Files.First();
                ResultFileName = file.Name;
                using (var stream = file.OpenText()) {
                    FileBody = stream.ReadToEnd();
                }
            }
        }
        [Command]
        public void Save() {
            SaveFileDialogService.DefaultExt = DefaultExt;
            SaveFileDialogService.DefaultFileName = DefaultFileName;
            SaveFileDialogService.Filter = Filter;
            SaveFileDialogService.FilterIndex = FilterIndex;
            DialogResult = SaveFileDialogService.ShowDialog();
            if (!DialogResult) {
                ResultFileName = string.Empty;
            } else {
                using (var stream = new StreamWriter(SaveFileDialogService.OpenFile())) {
                    stream.Write(FileBody);
                }
            }
        }
    }
}