Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.
How to Handle DiagramControl Events to Save Diagrams to a Database
7 minutes to read
This example demonstrates how to open and save diagrams to a custom storage (e.g., a database) instead of a file system. In the example, the following events are used to implement this functionality:
DiagramControl.ShowingOpenDialog - This event fires before the standard Open dialog is shown and allows you to customize the dialog options or replace the standard dialog with a custom one. You can also cancel the Open operation by setting the e.Cancel parameter to true.
DiagramControl.ShowingSaveDialog - Similarly to the ShowingOpenDialog event, the ShowingSaveDialog event allows you to customize the standard Save dialog in DiagramControl or replace it with a custom one. Setting the e.Cancel parameter to true will cancel the Save operation.
DiagramControl.CustomLoadDocument - This event fires after a user selected a document in the Open dialog or the DiagramControl.DocumentSource property was set in code. The event exposes the selected document source (e.g., a document name or a file stream) through the e.DocumentSource property and allows you to implement your own loading logic. For example, you can retrieve a diagram file from a database and load it into DiagramControl using the DiagramControl.LoadDocument property (as demonstrated in the example) or populate the diagram with items manually. After implementing your custom loading logic, set the e.Handled parameter to true, so that DiagramControl does not load the previously selected document source.
DiagramControl.CustomSaveDocument - The CustomSaveDocument event allows you to specify custom saving logic for your diagram. The event fires after the Save operation was initiated and selection was made in the Save dialog (if there was a dialog). The e.DocumentSource property specifies the default location (file name, stream, etc.) where the diagram will be saved. You can set the e.Handled parameter to true to cancel the standard saving logic and implement your custom one. For example, save the diagram to a stream using the DiagramControl.SaveDocument method as demonstrated in the example or iterate through diagram items manually and read required information.
ImportsDevExpress.Diagram.CoreImportsDevExpress.Xpf.CoreImportsDevExpress.Xpf.DiagramImportsSystemImportsSystem.Collections.GenericImportsSystem.Data.EntityImportsSystem.IOImportsSystem.LinqImports System.TextImportsSystem.Threading.TasksImportsSystem.WindowsNamespace DXDiagram.CustomDiagramStorage
FriendClass DiagramStorageInitializer
Inherits DropCreateDatabaseIfModelChanges(Of DiagramStorage)
ProtectedOverridesSub Seed(ByVal storage As DiagramStorage)
MyBase.Seed(storage)
Dim diagram = New DiagramControl()
For i AsInteger = 0To4
diagram.Items.Add(New DiagramShape() With {.Position = New Point(200, 100 + i * 100), .Width = 100, .Height = 50, .Content = "Item " & (i + 1).ToString()})
If i = 0ThenContinueForEndIfUsing stream = New MemoryStream()
diagram.SaveDocument(stream)
Dim diagramData = New DiagramData() With {.Name = (i + 1).ToString() & " items", .Data = stream.ToArray()}
storage.DiagramData.Add(diagramData)
EndUsingNext i
storage.SaveChanges()
EndSubEndClassEndNamespace
ImportsSystemImportsSystem.Collections.GenericImportsSystem.LinqImports System.TextImportsSystem.WindowsImportsSystem.Windows.ControlsImportsSystem.Windows.DataImportsSystem.Windows.DocumentsImportsSystem.Windows.InputImportsSystem.Windows.MediaImportsSystem.Windows.Media.ImagingImportsSystem.Windows.NavigationImportsSystem.Windows.ShapesImportsDevExpress.Xpf.CoreImportsDevExpress.Diagram.CoreImportsDevExpress.MvvmImports DevExpress.Mvvm.POCO
ImportsSystem.IONamespace DXDiagram.CustomDiagramStorage
'''<summary>''' Interaction logic for MainWindow.xaml'''</summary>PartialPublicClass MainWindow
Inherits DXWindow
PublicSubNew()
InitializeComponent()
EndSubPrivateSub OnLoaded(ByVal sender AsObject, ByVal e As RoutedEventArgs)
Dispatcher.BeginInvoke(New Action(AddressOf diagram.OpenFile))
EndSubPrivateSub OnShowingOpenDialog(ByVal sender AsObject, ByVal e As DevExpress.Xpf.Diagram.DiagramShowingOpenDialogEventArgs)
Dim viewModel = SelectDiagramViewModel.Create()
Dim result = openDialogService.ShowDialog(MessageButton.OKCancel, "Choose a diagram to open", viewModel)
If result = MessageResult.OK Then
e.DocumentSourceToOpen = viewModel.SelectedName
Else
e.Cancel = TrueEndIfEndSubPrivateSub OnCustomLoadDocument(ByVal sender AsObject, ByVal e As DevExpress.Xpf.Diagram.DiagramCustomLoadDocumentEventArgs)
If e.DocumentSource IsNothingThen
diagram.NewDocument()
ReturnEndIfDim storage = New DiagramStorage()
Dim diagramInfo = storage.DiagramData.FirstOrDefault(Function(x) x.Name = CStr(e.DocumentSource))
If diagramInfo IsNotNothingThen
diagram.LoadDocument(New MemoryStream(diagramInfo.Data))
EndIf
e.Handled = TrueEndSubPrivateSub OnShowingSaveDialog(ByVal sender AsObject, ByVal e As DevExpress.Xpf.Diagram.DiagramShowingSaveDialogEventArgs)
Dim viewModel = SelectDiagramViewModel.Create()
viewModel.SelectedName = CStr(diagram.DocumentSource)
Dim result = saveDialogService.ShowDialog(MessageButton.OKCancel, "Choose a save location", viewModel)
If result = MessageResult.OK Then
e.DocumentSourceToSave = viewModel.SelectedName
Else
e.Cancel = TrueEndIfEndSubPrivateSub OnCustomSaveDocument(ByVal sender AsObject, ByVal e As DevExpress.Xpf.Diagram.DiagramCustomSaveDocumentEventArgs)
Dim storage = New DiagramStorage()
Dim diagramInfo = storage.DiagramData.FirstOrDefault(Function(x) x.Name = CStr(e.DocumentSource))
If diagramInfo IsNothingThen
diagramInfo = New DiagramData() With {.Name = CStr(e.DocumentSource)}
storage.DiagramData.Add(diagramInfo)
EndIfDim stream = New MemoryStream()
diagram.SaveDocument(stream)
diagramInfo.Data = stream.ToArray()
storage.SaveChanges()
e.Handled = TrueEndSubEndClassPublicClass SelectDiagramViewModel
PublicSharedFunction Create() As SelectDiagramViewModel
Return ViewModelSource.Create(Function() New SelectDiagramViewModel())
EndFunctionProtectedSubNew()
Dim storage = New DiagramStorage()
Names = storage.DiagramData.Select(Function(x) x.Name).ToArray()
SelectedName = Names.FirstOrDefault()
EndSubPrivate privateNames AsString()
PublicProperty Names() AsString()
GetReturn privateNames
EndGetPrivateSet(ByVal value AsString())
privateNames = value
EndSetEndPropertyPublicOverridableProperty SelectedName() AsStringEndClassEndNamespace
usingDevExpress.Diagram.Core;
usingDevExpress.Xpf.Core;
usingDevExpress.Xpf.Diagram;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data.Entity;
usingSystem.IO;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
namespaceDXDiagram.CustomDiagramStorage {
classDiagramStorageInitializer : DropCreateDatabaseIfModelChanges<DiagramStorage> {
protectedoverridevoidSeed(DiagramStorage storage) {
base.Seed(storage);
var diagram = new DiagramControl();
for(int i = 0; i < 5; i++) {
diagram.Items.Add(new DiagramShape() {
Position = new Point(200, 100 + i * 100),
Width = 100,
Height = 50,
Content = "Item " + (i + 1).ToString(),
});
if(i == 0)
continue;
using(var stream = new MemoryStream()) {
diagram.SaveDocument(stream);
var diagramData = new DiagramData() {
Name = (i + 1).ToString() + " items",
Data = stream.ToArray(),
};
storage.DiagramData.Add(diagramData);
}
}
storage.SaveChanges();
}
}
}
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Navigation;
usingSystem.Windows.Shapes;
usingDevExpress.Xpf.Core;
usingDevExpress.Diagram.Core;
usingDevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
usingSystem.IO;
namespaceDXDiagram.CustomDiagramStorage {
///<summary>/// Interaction logic for MainWindow.xaml///</summary>publicpartialclassMainWindow : DXWindow {
publicMainWindow() {
InitializeComponent();
}
privatevoidOnLoaded(object sender, RoutedEventArgs e) {
Dispatcher.BeginInvoke(new Action(diagram.OpenFile));
}
privatevoidOnShowingOpenDialog(object sender, DevExpress.Xpf.Diagram.DiagramShowingOpenDialogEventArgs e) {
var viewModel = SelectDiagramViewModel.Create();
var result = openDialogService.ShowDialog(MessageButton.OKCancel, "Choose a diagram to open", viewModel);
if(result == MessageResult.OK)
e.DocumentSourceToOpen = viewModel.SelectedName;
else
e.Cancel = true;
}
privatevoidOnCustomLoadDocument(object sender, DevExpress.Xpf.Diagram.DiagramCustomLoadDocumentEventArgs e) {
if(e.DocumentSource == null) {
diagram.NewDocument();
return;
}
var storage = new DiagramStorage();
var diagramInfo = storage.DiagramData.FirstOrDefault(x => x.Name == (string)e.DocumentSource);
if(diagramInfo != null)
diagram.LoadDocument(new MemoryStream(diagramInfo.Data));
e.Handled = true;
}
privatevoidOnShowingSaveDialog(object sender, DevExpress.Xpf.Diagram.DiagramShowingSaveDialogEventArgs e) {
var viewModel = SelectDiagramViewModel.Create();
viewModel.SelectedName = (string)diagram.DocumentSource;
var result = saveDialogService.ShowDialog(MessageButton.OKCancel, "Choose a save location", viewModel);
if(result == MessageResult.OK)
e.DocumentSourceToSave = viewModel.SelectedName;
else
e.Cancel = true;
}
privatevoidOnCustomSaveDocument(object sender, DevExpress.Xpf.Diagram.DiagramCustomSaveDocumentEventArgs e) {
var storage = new DiagramStorage();
var diagramInfo = storage.DiagramData.FirstOrDefault(x => x.Name == (string)e.DocumentSource);
if(diagramInfo == null) {
diagramInfo = new DiagramData() { Name = (string)e.DocumentSource };
storage.DiagramData.Add(diagramInfo);
}
var stream = new MemoryStream();
diagram.SaveDocument(stream);
diagramInfo.Data = stream.ToArray();
storage.SaveChanges();
e.Handled = true;
}
}
publicclassSelectDiagramViewModel {
publicstatic SelectDiagramViewModel Create() {
return ViewModelSource.Create(() => new SelectDiagramViewModel());
}
protectedSelectDiagramViewModel() {
var storage = new DiagramStorage();
Names = storage.DiagramData.Select(x => x.Name).ToArray();
SelectedName = Names.FirstOrDefault();
}
publicstring[] Names { get; privateset; }
publicvirtualstring SelectedName { get; set; }
}
}