New to Telerik UI for WPF? Download free 30-day trial

DiagramToolbox

This article describes the main features and properties of the RadDiagramToolbox control. You can examine the behavior of the control in the Diagrams DesignToolbox demo.

In order to use the RadDiagramToolbox control in your projects you have to add references to the following assemblies:

  • Telerik.Windows.Controls
  • Telerik.Windows.Controls.Diagrams
  • Telerik.Windows.Controls.Diagrams.Extensions
  • Telerik.Windows.Controls.Input
  • Telerik.Windows.Controls.Navigation
  • Telerik.Windows.Data
  • Telerik.Windows.Diagrams.Core

Please note that the examples in this tutorial are showcasing Telerik Windows8 theme. In the Setting a Theme article you can find more information on how to set an application-wide theme.

Visual Structure And Properties

The Diagram Extensions include a RadDiagramToolbox control. It is designed to display multiple galleries of RadDiagramShapes in a single control. Below you can see a snapshot and explanation of the main visual elements of the control. Rad Diagram Extensions Toolbox Overview

The RadDiagramToolbox exposes the following list of properties:

  • Header - gets or sets an object that represents the RadDiagramToolbox header.

  • HeaderTemplate - gets or sets the DataTemplate used to display the header.

  • Title - gets or sets an object that represents the RadDiagramToolbox title.

  • TitleTemplate - gets or sets the DataTemplate used to display the title of the toolbox.

  • IsOpen - gets or sets a value that indicates whether the groups area of the RadDiagramToolbox control is visible.

  • CloseButtonStyle - gets or sets the style used by the Close button when it is rendered.

  • OpenCloseButtonStyle - gets or sets the style used by the OpenClose button when it is rendered.

  • Items - gets or sets the collection used to generate the content of the RadDiagramToolbox.

  • ItemsSource - gets or sets a business collection used to generate the content of the RadDiagramToolbox.

How to Use the Predefined HierarchicalGalleryItemsCollection

The Diagram Extensions provide a HierarchicalGalleryItemsCollection which is an ObservableCollection of galleries with predefined RadDiagramShapes. You can use it to populate the RadDiagramToolbox.ItemsSource collection with business items.

You can use it directly in XAML:

<Grid> 
        <Grid.DataContext> 
            <telerik:HierarchicalGalleryItemsCollection /> 
        </Grid.DataContext> 
        <Grid.Resources> 
            <telerik:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
            <!--  ToolboxItemTemplate  --> 
                <DataTemplate x:Key="ToolboxItemTemplate"> 
                    <Grid Width="76" 
                        Height="100" 
                        Margin="0 1 1 0"> 
                        <Grid.RowDefinitions> 
                            <RowDefinition Height="*" /> 
                            <RowDefinition Height="42" /> 
                        </Grid.RowDefinitions> 
                        <Viewbox Margin="5 5 5 0" 
                                HorizontalAlignment="Center" 
                                VerticalAlignment="Bottom"> 
                            <ContentPresenter Margin="5" 
                                            Content="{Binding Shape}" 
                                            IsHitTestVisible="False" /> 
                        </Viewbox> 
                        <TextBlock Grid.Row="1" 
                                Margin="5" 
                                HorizontalAlignment="Center" 
                                VerticalAlignment="Top" 
                                FontFamily="Segoe UI Semibold" 
                                FontSize="12" 
                                Text="{Binding Header}" 
                                TextAlignment="Center" 
                                TextWrapping="Wrap" /> 
                    </Grid> 
                </DataTemplate> 
                <!--  ToolboxGroupTemplate  --> 
                <HierarchicalDataTemplate x:Key="ToolboxTemplate" 
                                        ItemTemplate="{StaticResource ToolboxItemTemplate}" 
                                        ItemsSource="{Binding Items}"> 
                    <TextBlock MinWidth="55" Text="{Binding Header}" /> 
                </HierarchicalDataTemplate> 
        </Grid.Resources> 
        <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="Auto" /> 
 
 
    </Grid.ColumnDefinitions> 
 
    <telerik:RadDiagramToolbox x:Name="toolbox" 
                            Title="Gallery" 
                            Width="330" 
                            HorizontalAlignment="Right" 
                            Header="{Binding SelectedItem.Header, 
                                                RelativeSource={RelativeSource Self}}" 
                            ItemsSource="{Binding}" 
                            ItemTemplate="{StaticResource ToolboxTemplate}" 
                            Visibility="{Binding IsChecked, 
                                                    ElementName=toolboxButton, 
                                                    Converter={StaticResource BooleanToVisibilityConverter}}" /> 
 
</Grid> 

or define a property of type HierarchicalGalleryItemsCollection in your ViewModel:

public class MainViewModel 
{ 
    public HierarchicalGalleryItemsCollection GalleryItems { get; set; } 
 
    public MainViewModel() 
    { 
        this.GalleryItems = new HierarchicalGalleryItemsCollection(); 
    } 
} 
Public Class MainViewModel 
    Public Property GalleryItems() As HierarchicalGalleryItemsCollection 
        Get 
            Return _GalleryItems 
        End Get 
        Set 
            _GalleryItems = Value 
        End Set 
    End Property 
    Private _GalleryItems As HierarchicalGalleryItemsCollection 
 
    Public Sub New() 
        Me.GalleryItems = New HierarchicalGalleryItemsCollection() 
    End Sub 
End Class    

<Grid> 
    <Grid.DataContext> 
         <!-- local is an alias pointing to your local namespace where the MainViewModel class is defined--> 
        <local:MainViewModel /> 
    </Grid.DataContext> 
    <Grid.Resources> 
        <telerik:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
           <!--  ToolboxItemTemplate  --> 
            <DataTemplate x:Key="ToolboxItemTemplate"> 
                <Grid Width="76" 
                      Height="100" 
                      Margin="0 1 1 0"> 
                    <Grid.RowDefinitions> 
                        <RowDefinition Height="*" /> 
                        <RowDefinition Height="42" /> 
                    </Grid.RowDefinitions> 
                    <Viewbox Margin="5 5 5 0" 
                             HorizontalAlignment="Center" 
                             VerticalAlignment="Bottom"> 
                        <ContentPresenter Margin="5" 
                                          Content="{Binding Shape}" 
                                          IsHitTestVisible="False" /> 
                    </Viewbox> 
                    <TextBlock Grid.Row="1" 
                               Margin="5" 
                               HorizontalAlignment="Center" 
                               VerticalAlignment="Top" 
                               FontFamily="Segoe UI Semibold" 
                               FontSize="12" 
                               Text="{Binding Header}" 
                               TextAlignment="Center" 
                               TextWrapping="Wrap" /> 
                </Grid> 
            </DataTemplate> 
            <!--  ToolboxGroupTemplate  --> 
            <HierarchicalDataTemplate x:Key="ToolboxTemplate" 
                                      ItemTemplate="{StaticResource ToolboxItemTemplate}" 
                                      ItemsSource="{Binding Items}"> 
                <TextBlock MinWidth="55" Text="{Binding Header}" /> 
            </HierarchicalDataTemplate> 
    </Grid.Resources> 
 
 
    <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="Auto" /> 
 
    </Grid.ColumnDefinitions> 
 
    <telerik:RadDiagramToolbox x:Name="toolbox" 
                               Title="Gallery" 
                               Width="330" 
                               HorizontalAlignment="Right" 
                               Header="{Binding SelectedItem.Header, 
                                                RelativeSource={RelativeSource Self}}" 
                               ItemsSource="{Binding GalleryItems}" 
                               ItemTemplate="{StaticResource ToolboxTemplate}" 
                               Visibility="{Binding IsChecked, 
                                                    ElementName=toolboxButton, 
                                                    Converter={StaticResource BooleanToVisibilityConverter}}" /> 
 
</Grid> 

Configure a RadDiagramToolbox to Display Part of the HierarchicalGalleryItemsCollection

The HierarchicalGalleryItemsCollection is populated based on the items in the Telerik.Windows.Controls.Diagrams.Extensions.GalleryItemsCollection grouped by the name of each gallery. This is why you can easily recreate it in your ViewModel:

public class MainViewModel 
{ 
    public ObservableCollection<Gallery> GalleryItems { get; set; } 
 
    public MainViewModel() 
    { 
        this.GalleryItems = new ObservableCollection<Gallery>(); 
        LoadData("Basic", "Flowchart", "Arrow", "Container"); 
    } 
 
    private void LoadData(params string[] galleryNames) 
    { 
        var allItems = new GalleryItemsCollection(); 
 
        foreach (var galleryName in galleryNames) 
        { 
            var gallery = new Gallery { Header = galleryName }; 
            foreach (var item in allItems.GetItemsByType(galleryName).ToArray()) 
            { 
                gallery.Items.Add(item); 
            } 
            this.GalleryItems.Add(gallery); 
        } 
    } 
}    
Public Class MainViewModel 
    Public Property GalleryItems() As ObservableCollection(Of Gallery) 
        Get 
            Return _GalleryItems 
        End Get 
        Set 
            _GalleryItems = Value 
        End Set 
    End Property 
    Private _GalleryItems As ObservableCollection(Of Gallery) 
 
    Public Sub New() 
        Me.GalleryItems = New ObservableCollection(Of Gallery)() 
        LoadData("Basic", "Flowchart", "Arrow","Container") 
    End Sub 
 
    Private Sub LoadData(ParamArray galleryNames As String()) 
        Dim allItems = New GalleryItemsCollection() 
 
        For Each galleryName As var In galleryNames 
            Dim gallery = New Gallery() With { .Header = galleryName } 
            For Each item As var In allItems.GetItemsByType(galleryName).ToArray() 
                gallery.Items.Add(item) 
            Next 
            Me.GalleryItems.Add(gallery) 
        Next 
    End Sub 
End Class    

Next, you can customize your GalleryItems collection to display only the Basic Shapes gallery like so:

public class MainViewModel 
{ 
    public ObservableCollection<Gallery> GalleryItems { get; set; } 
 
    public MainViewModel() 
    { 
        this.GalleryItems = new ObservableCollection<Gallery>(); 
        LoadData("Basic"); 
    } 
 
    private void LoadData(params string[] galleryNames) 
    { 
        var allItems = new GalleryItemsCollection(); 
 
        foreach (var galleryName in galleryNames) 
        { 
            var gallery = new Gallery { Header = galleryName }; 
            foreach (var item in allItems.GetItemsByType(galleryName).ToArray()) 
            { 
                gallery.Items.Add(item); 
            } 
            this.GalleryItems.Add(gallery); 
        } 
    } 
} 
Public Class MainViewModel 
    Public Property GalleryItems() As ObservableCollection(Of Gallery) 
        Get 
            Return _GalleryItems 
        End Get 
        Set 
            _GalleryItems = Value 
        End Set 
    End Property 
    Private _GalleryItems As ObservableCollection(Of Gallery) 
 
    Public Sub New() 
        Me.GalleryItems = New ObservableCollection(Of Gallery)() 
        LoadData("Basic") 
    End Sub 
 
    Private Sub LoadData(ParamArray galleryNames As String()) 
        Dim allItems = New GalleryItemsCollection() 
 
        For Each galleryName As var In galleryNames 
            Dim gallery = New Gallery() With { .Header = galleryName} 
            For Each item As var In allItems.GetItemsByType(galleryName).ToArray() 
                gallery.Items.Add(item) 
            Next 
            Me.GalleryItems.Add(gallery) 
        Next 
    End Sub 
End Class 

Rad Diagram Extensions Toolbox Basic Shapes

How to Populate RadDiagramToolbox with Custom Data Items

In case you need to populate a RadDiagramToolbox instance with a custom collection of business items, you will have to create a hierarchical collection of items. The first-level items of the collection should represent the galleries, whilst the second-level items should describe the shapes within the RadDiagramToolbox.

For the purpose of this tutorial we will create a class describing our shapes and a custom gallery class that defines a collection of shapes:

public class MyShape 
{ 
    public Geometry Geometry { get; set; } 
    public string Header { get; set; } 
} 
public class MyGallery 
{ 
    public string Header { get; set; } 
    public ObservableCollection<MyShape> Shapes { get; set; } 
    public MyGallery() 
    { 
        this.Shapes = new ObservableCollection<MyShape>(); 
    } 
} 
public class MainViewModel 
{ 
    public ObservableCollection<MyGallery> Items { get; set; } 
    public MainViewModel() 
    { 
        this.Items = new ObservableCollection<MyGallery>(); 
        //create and populate the first custom gallery 
        MyGallery firstGallery = new MyGallery { Header = "First Gallery" }; 
        firstGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 1.1", 
            Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.CloudShape) 
        }); 
        firstGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 1.2", 
            Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.EllipseShape) 
        }); 
        firstGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 1.3", 
            Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.HexagonShape) 
        }); 
        firstGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 1.4", 
            Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.PentagonShape) 
        }); 
        firstGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 1.5", 
            Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.RightTriangleShape) 
        }); 
        this.Items.Add(firstGallery); 
 
        //create and populate the second custom gallery 
        MyGallery secondGallery = new MyGallery { Header = "Second Gallery" }; 
        secondGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 2.1", 
            Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.CardShape) 
        }); 
        secondGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 2.2", 
            Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.Database1Shape) 
        }); 
        secondGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 2.3", 
            Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.CollateShape) 
        }); 
        secondGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 2.4", 
            Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.DataShape) 
        }); 
        secondGallery.Shapes.Add(new MyShape 
        { 
            Header = "Shape 2.5", 
            Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.DisplayShape) 
        }); 
        this.Items.Add(secondGallery); 
    } 
} 
Public Class MyShape 
    Public Property Geometry() As Geometry 
    Public Property Header() As String 
End Class 
Public Class MyGallery 
    Public Property Header() As String 
    Public Property Shapes() As ObservableCollection(Of MyShape) 
    Public Sub New() 
        Me.Shapes = New ObservableCollection(Of MyShape)() 
    End Sub 
End Class 
Public Class MainViewModel 
    Public Property Items() As ObservableCollection(Of MyGallery) 
    Public Sub New() 
        Me.Items = New ObservableCollection(Of MyGallery)() 
        'create and populate the first custom gallery' 
        Dim firstGallery As MyGallery = New MyGallery With {.Header = "First Gallery"} 
        firstGallery.Shapes.Add(New MyShape With {.Header = "Shape 1.1", .Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.CloudShape)}) 
        firstGallery.Shapes.Add(New MyShape With {.Header = "Shape 1.2", .Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.EllipseShape)}) 
        firstGallery.Shapes.Add(New MyShape With {.Header = "Shape 1.3", .Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.HexagonShape)}) 
        firstGallery.Shapes.Add(New MyShape With {.Header = "Shape 1.4", .Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.PentagonShape)}) 
        firstGallery.Shapes.Add(New MyShape With {.Header = "Shape 1.5", .Geometry = ShapeFactory.GetShapeGeometry(CommonShapeType.RightTriangleShape)}) 
        Me.Items.Add(firstGallery) 
 
        'create and populate the second custom gallery' 
        Dim secondGallery As MyGallery = New MyGallery With {.Header = "Second Gallery"} 
        secondGallery.Shapes.Add(New MyShape With {.Header = "Shape 2.1", .Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.CardShape)}) 
        secondGallery.Shapes.Add(New MyShape With {.Header = "Shape 2.2", .Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.Database1Shape)}) 
        secondGallery.Shapes.Add(New MyShape With {.Header = "Shape 2.3", .Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.CollateShape)}) 
        secondGallery.Shapes.Add(New MyShape With {.Header = "Shape 2.4", .Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.DataShape)}) 
        secondGallery.Shapes.Add(New MyShape With {.Header = "Shape 2.5", .Geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.DisplayShape)}) 
        Me.Items.Add(secondGallery) 
    End Sub 
End Class 

Once the ViewModels are all in place, you can use the MainViewModel as the DataContext of the RadDiagramToolbox and bind its ItemsSource to the Items collection. You will also need to define DataTemplates to visualize the MyShape and MyGallery items properly.

<Grid> 
    <Grid.DataContext> 
        <local:MainViewModel /> 
    </Grid.DataContext> 
    <Grid.Resources> 
        <telerik:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
        <!--  ToolboxItemTemplate  --> 
        <DataTemplate x:Key="ToolboxItemTemplate"> 
            <Border Width="76" 
                    Height="100" 
                    Margin="0 1 1 0" 
                    Background="Transparent"> 
                <Grid> 
                    <Grid.RowDefinitions> 
                        <RowDefinition Height="*" /> 
                        <RowDefinition Height="Auto" /> 
                    </Grid.RowDefinitions> 
                    <Viewbox Width="64" 
                             Height="50" 
                             Margin="5 10 5 0" 
                             HorizontalAlignment="Center" 
                             VerticalAlignment="Top" 
                             Stretch="Uniform"> 
                        <telerik:RadDiagramShape Margin="15" 
                                                 VerticalAlignment="Top" 
                                                 HorizontalContentAlignment="Center" 
                                                 VerticalContentAlignment="Center" 
                                                 Geometry="{Binding Geometry}" 
                                                 IsHitTestVisible="False" /> 
                    </Viewbox> 
                    <TextBlock Grid.Row="1" 
                               Margin="0 0 0 5" 
                               HorizontalAlignment="Center" 
                               FontFamily="Segoe UI Semibold" 
                               Padding="4 0" 
                               Text="{Binding Header}" 
                               TextAlignment="Center" 
                               TextWrapping="Wrap" /> 
                </Grid> 
            </Border> 
 
        </DataTemplate> 
        <!--  ToolboxGroupTemplate  --> 
        <HierarchicalDataTemplate x:Key="ToolboxGroupTemplate" 
                                  ItemsSource="{Binding Shapes}" 
                                  ItemTemplate="{StaticResource ToolboxItemTemplate}"> 
            <TextBlock Text="{Binding Header}" /> 
        </HierarchicalDataTemplate> 
    </Grid.Resources> 
 
    <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="Auto" /> 
 
    </Grid.ColumnDefinitions> 
 
    <telerik:RadDiagramToolbox x:Name="toolbox" 
                               Title="Gallery" 
                               Width="330" 
                               HorizontalAlignment="Right" 
                               Header="{Binding SelectedItem.Header, 
                                                RelativeSource={RelativeSource Self}}" 
                               ItemsSource="{Binding Items}" 
                               ItemTemplate="{StaticResource ToolboxGroupTemplate}" 
                               Visibility="{Binding IsChecked, 
                                                    ElementName=toolboxButton, 
                                                    Converter={StaticResource BooleanToVisibilityConverter}}" /> 
 
</Grid> 

Rad Diagram Extensions Toolbox Custom Gallery

DragDrop Support

RadDiagramToolbox supports drag/drop operations out-of-the-box. As soon as a RadDiagramToolboxItem is initialized, it is made draggable through the DragDropManager AllowDrag and AllowCapturedDrag properties which are both set to true. Moreover, the Diagramming Framework internally handles the DragDropManager DragInitialize event to take from the dragged RadDiagramToolboxItem the shape it represents, if sush exists, and serialize its settings. The serialized settings are then saved in a DiagramDropInfo object along with the actual size of the dragged shape.

The DiagramDropInfo structure describes a dragged object within a RadDiagram instance. It includes a SerializationInfo property and a Size property – the first one holds the serialized settings of the dragged RadDiagramItem, while the second holds the actual size of the dragged item.

Due to this built-in DragDropManager drag implementation, you can easily drag shapes and containers out of a RadDiagramToolbox and drop them onto a diagramming surface. RadDiagram knows how to extract the serialized information out of a DiagramDropInfo object to create a new RadDiagramItem on the surface. However, if you create a custom RadDiagramToolbox populated with a business collection of items, you will have to further configure the drag/drop operation. Please have a look at the How To Drag Items from a Custom Databound DiagramToolbox tutorial for instructions on how to implement such a scenario.

See Also

In this article