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 method (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 - This 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 in the event args 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.
View Example
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
namespace XtraDiagram.CustomDiagramStorage {
public partial class DiagramOpenDialog : DevExpress.XtraEditors.XtraForm {
public string SelectedItem { get; set; }
public DiagramOpenDialog() {
InitializeComponent();
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
PopulateListBox();
}
private void PopulateListBox() {
if (!DesignMode)
listBoxControl1.DataSource = DiagramRepository.GetDiagramNames();
}
private void listBoxControl1_MouseDoubleClick(object sender, MouseEventArgs e) {
var itemIndex = listBoxControl1.IndexFromPoint(e.Location);
if (itemIndex > -1) {
DialogResult = DialogResult.OK;
Close();
}
}
private void listBoxControl1_SelectedIndexChanged(object sender, EventArgs e) {
OnSelectedItemChanged();
}
protected virtual void OnSelectedItemChanged() {
SelectedItem = listBoxControl1.SelectedItem as string;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace XtraDiagram.CustomDiagramStorage {
public class DiagramSelector {
public static string SelectDiagramToOpen() {
var selector = new DiagramOpenDialog() { Text = "Choose a diagram to open" };
return ShowDialogCore(selector);
}
public static string SelectDiagramToSave() {
var selector = new DiagramSaveDialog() { Text = "Choose a save location" };
return ShowDialogCore(selector);
}
protected static string ShowDialogCore(DiagramOpenDialog dialog) {
dialog.ShowDialog();
return dialog.DialogResult == DialogResult.OK ? dialog.SelectedItem : null;
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
namespace XtraDiagram.CustomDiagramStorage {
public partial class DiagramSaveDialog : DiagramOpenDialog {
public DiagramSaveDialog() {
InitializeComponent();
}
protected override void OnSelectedItemChanged() {
base.OnSelectedItemChanged();
textEdit1.Text = SelectedItem;
}
protected override void OnClosing(CancelEventArgs e) {
base.OnClosing(e);
SelectedItem = textEdit1.Text;
}
}
}
using DevExpress.Diagram.Core;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using DevExpress.XtraDiagram;
namespace XtraDiagram.CustomDiagramStorage {
class DiagramStorageInitializer : DropCreateDatabaseIfModelChanges<DiagramStorage> {
protected override void Seed(DiagramStorage storage) {
base.Seed(storage);
var diagram = new DiagramControl();
for(int i = 0; i < 5; i++) {
diagram.Items.Add(new DiagramShape() {
Position = new DevExpress.Utils.PointFloat(200, 100 + i * 100),
Width = 100,
Height = 50,
Content = "Item " + (i + 1).ToString(),
});
if(i == 0)
continue;
diagram.SelectedStencils = new StencilCollection(new string[] {
DiagramToolboxRegistrator.Stencils.ElementAt(i).Id
});
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();
}
}
}
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Windows.Forms;
using DevExpress.Internal;
namespace XtraDiagram.CustomDiagramStorage {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory();
Database.SetInitializer(new DiagramStorageInitializer());
Application.Run(new Form1());
}
}
}
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XtraDiagram.CustomDiagramStorage {
public class DiagramStorage : DbContext {
public DbSet<DiagramData> DiagramData { get; set; }
}
public class DiagramData {
public int Id { get; set; }
public string Name { get; set; }
public byte[] Data { get; set; }
}
public class DiagramRepository {
public static IEnumerable<string> GetDiagramNames() {
var storage = new DiagramStorage();
return storage.DiagramData.Select(x => x.Name).ToList();
}
public static byte[] GetDiagramData(string diagramName) {
var storage = new DiagramStorage();
return storage.DiagramData.FirstOrDefault(x => x.Name == diagramName).Data;
}
public static void SaveDiagramData(string diagramName, byte[] diagramData) {
var storage = new DiagramStorage();
var diagramInfo = storage.DiagramData.FirstOrDefault(x => x.Name == diagramName);
if (diagramInfo == null) {
diagramInfo = new DiagramData() { Name = diagramName };
storage.DiagramData.Add(diagramInfo);
}
diagramInfo.Data = diagramData;
storage.SaveChanges();
}
}
}
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Linq
Imports System.Windows.Forms
Imports DevExpress.XtraEditors
Namespace XtraDiagram.CustomDiagramStorage
Partial Public Class DiagramSaveDialog
Inherits DiagramOpenDialog
Public Sub New()
InitializeComponent()
End Sub
Protected Overrides Sub OnSelectedItemChanged()
MyBase.OnSelectedItemChanged()
textEdit1.Text = SelectedItem
End Sub
Protected Overrides Sub OnClosing(ByVal e As CancelEventArgs)
MyBase.OnClosing(e)
SelectedItem = textEdit1.Text
End Sub
End Class
End Namespace
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Linq
Imports System.Windows.Forms
Imports DevExpress.XtraEditors
Namespace XtraDiagram.CustomDiagramStorage
Partial Public Class DiagramOpenDialog
Inherits DevExpress.XtraEditors.XtraForm
Public Property SelectedItem() As String
Public Sub New()
InitializeComponent()
End Sub
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
PopulateListBox()
End Sub
Private Sub PopulateListBox()
If Not DesignMode Then
listBoxControl1.DataSource = DiagramRepository.GetDiagramNames()
End If
End Sub
Private Sub listBoxControl1_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs) Handles listBoxControl1.MouseDoubleClick
Dim itemIndex = listBoxControl1.IndexFromPoint(e.Location)
If itemIndex > -1 Then
DialogResult = DialogResult.OK
Close()
End If
End Sub
Private Sub listBoxControl1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles listBoxControl1.SelectedIndexChanged
OnSelectedItemChanged()
End Sub
Protected Overridable Sub OnSelectedItemChanged()
SelectedItem = TryCast(listBoxControl1.SelectedItem, String)
End Sub
End Class
End Namespace
Imports System
Imports System.Collections.Generic
Imports System.Data.Entity
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Namespace XtraDiagram.CustomDiagramStorage
Public Class DiagramStorage
Inherits DbContext
Public Property DiagramData() As DbSet(Of DiagramData)
End Class
Public Class DiagramData
Public Property Id() As Integer
Public Property Name() As String
Public Property Data() As Byte()
End Class
Public Class DiagramRepository
Public Shared Function GetDiagramNames() As IEnumerable(Of String)
Dim storage = New DiagramStorage()
Return storage.DiagramData.Select(Function(x) x.Name).ToList()
End Function
Public Shared Function GetDiagramData(ByVal diagramName As String) As Byte()
Dim storage = New DiagramStorage()
Return storage.DiagramData.FirstOrDefault(Function(x) x.Name = diagramName).Data
End Function
Public Shared Sub SaveDiagramData(ByVal diagramName As String, ByVal diagramData() As Byte)
Dim storage = New DiagramStorage()
Dim diagramInfo = storage.DiagramData.FirstOrDefault(Function(x) x.Name = diagramName)
If diagramInfo Is Nothing Then
diagramInfo = New DiagramData() With {.Name = diagramName}
storage.DiagramData.Add(diagramInfo)
End If
diagramInfo.Data = diagramData
storage.SaveChanges()
End Sub
End Class
End Namespace
Imports DevExpress.Diagram.Core
Imports System
Imports System.Collections.Generic
Imports System.Data.Entity
Imports System.IO
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows
Imports DevExpress.XtraDiagram
Namespace XtraDiagram.CustomDiagramStorage
Friend Class DiagramStorageInitializer
Inherits DropCreateDatabaseIfModelChanges(Of DiagramStorage)
Protected Overrides Sub Seed(ByVal storage As DiagramStorage)
MyBase.Seed(storage)
Dim diagram = New DiagramControl()
For i As Integer = 0 To 4
diagram.Items.Add(New DiagramShape() With {.Position = New DevExpress.Utils.PointFloat(200, 100 + i * 100), .Width = 100, .Height = 50, .Content = "Item " & (i + 1).ToString()})
If i = 0 Then
Continue For
End If
diagram.SelectedStencils = New StencilCollection(New String() { DiagramToolboxRegistrator.Stencils.ElementAt(i).Id })
Using stream = New MemoryStream()
diagram.SaveDocument(stream)
Dim diagramData = New DiagramData() With {.Name = (i + 1).ToString() & " items", .Data = stream.ToArray()}
storage.DiagramData.Add(diagramData)
End Using
Next i
storage.SaveChanges()
End Sub
End Class
End Namespace
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Namespace XtraDiagram.CustomDiagramStorage
Public Class DiagramSelector
Public Shared Function SelectDiagramToOpen() As String
Dim selector = New DiagramOpenDialog() With {.Text = "Choose a diagram to open"}
Return ShowDialogCore(selector)
End Function
Public Shared Function SelectDiagramToSave() As String
Dim selector = New DiagramSaveDialog() With {.Text = "Choose a save location"}
Return ShowDialogCore(selector)
End Function
Protected Shared Function ShowDialogCore(ByVal dialog As DiagramOpenDialog) As String
dialog.ShowDialog()
Return If(dialog.DialogResult = DialogResult.OK, dialog.SelectedItem, Nothing)
End Function
End Class
End Namespace
Imports System
Imports System.Collections.Generic
Imports System.Data.Entity
Imports System.Linq
Imports System.Windows.Forms
Imports DevExpress.Internal
Namespace XtraDiagram.CustomDiagramStorage
Friend NotInheritable Class Program
Private Sub New()
End Sub
''' <summary>
''' The main entry point for the application.
''' </summary>
<STAThread> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
DbEngineDetector.PatchConnectionStringsAndConfigureEntityFrameworkDefaultConnectionFactory()
Database.SetInitializer(New DiagramStorageInitializer())
Application.Run(New Form1())
End Sub
End Class
End Namespace