Place Rad Controls in Diagram Shapes

This tutorial demonstrates how to use UI for Silverlight in the content of a RadDiagramShape component.

As the RadDiagramShape essentially derives from a ContentControl, its Content can wrap other controls. For the purpose of this tutorial we will use a RadCalendar and a RadGridView and will display both in RadDiagramShapes. We will also connect these shapes with a RadDiagramConnection.

Let's start by defining a RadDiagram instance in our view:

<Grid x:Name="LayoutRoot" Background="White"> 
    <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock HorizontalAlignment="Center" Text="Hosting Telerik controls in shapes" /> 
    <telerik:RadDiagram x:Name="diagram"  
                        Grid.Row="1"  
                        Grid.RowSpan="1"  
                        ActiveTool="PointerTool"  
                        Background="White" 
                        IsBackgroundSurfaceVisible="false"  
                        Zoom="1"> 
    </telerik:RadDiagram> 
</Grid> 

Next, we can add a RadDiagramShape that contains a RadGridView component. We will define these controls in our XAML view:

<Grid x:Name="LayoutRoot" Background="White"> 
    <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock HorizontalAlignment="Center" Text="Hosting Telerik controls in shapes" /> 
    <telerik:RadDiagram x:Name="diagram"  
                        Grid.Row="1"  
                        Grid.RowSpan="1"  
                        ActiveTool="PointerTool"  
                        Background="White" 
                        IsBackgroundSurfaceVisible="false"  
                        Zoom="1"> 
        <telerik:RadDiagramShape x:Name="gridShape"  
                                Position="600,50"  
                                UseGlidingConnector="true" 
                                HorizontalContentAlignment="Stretch"  
                                VerticalContentAlignment="Stretch"> 
            <Grid> 
                <Grid.RowDefinitions> 
                    <RowDefinition Height="30" /> 
                    <RowDefinition /> 
                </Grid.RowDefinitions> 
                <TextBlock Text="Dragging area" HorizontalAlignment="Center" FontSize="16" /> 
                <telerik:RadGridView ItemsSource="{Binding}"  
                                    Grid.Row="1"  
                                    Background="LightBlue" 
                                    BorderBrush="SteelBlue" /> 
            </Grid> 
        </telerik:RadDiagramShape> 
    </telerik:RadDiagram> 
</Grid> 

If you run the solution at this point, you should get the following diagramming structure: raddiagram-howto-radcontrols-empty-gridview

And as our RadGridView is currently empty, we can go ahead and populate it with sample data. For that purpose, we first need to define a custom data class - let's name it ProductSales:

public class ProductSales 
{ 
    public ProductSales(int quantity, int month, string monthName) 
    { 
        this.Quantity = quantity; 
        this.Month = month; 
        this.MonthName = monthName; 
    } 
 
    public int Quantity { get; set; } 
    public int Month { get; set; } 
    public string MonthName { get; set; } 
} 
Public Class ProductSales 
    Public Sub New(quantity As Integer, month As Integer, monthName As String) 
        Me.Quantity = quantity 
        Me.Month = month 
        Me.MonthName = monthName 
    End Sub 
 
    Public Property Quantity() As Integer 
        Get 
            Return m_Quantity 
        End Get 
        Set(value As Integer) 
            m_Quantity = Value 
        End Set 
    End Property 
    Private m_Quantity As Integer 
    Public Property Month() As Integer 
        Get 
            Return m_Month 
        End Get 
        Set(value As Integer) 
            m_Month = Value 
        End Set 
    End Property 
    Private m_Month As Integer 
    Public Property MonthName() As String 
        Get 
            Return m_MonthName 
        End Get 
        Set(value As String) 
            m_MonthName = Value 
        End Set 
    End Property 
    Private m_MonthName As String 
End Class 

Next in our code-behind we can create a method that returns a list of ProductSales and use its result as a DataContext of the view:

private static List<ProductSales> GetProductSales() 
{ 
    var persons = new List<ProductSales> 
    { 
        new ProductSales(154, 1, "January"),  
        new ProductSales(138, 2, "February"),  
        new ProductSales(143, 3, "March"),  
        new ProductSales(120, 4, "April"),  
        new ProductSales(135, 5, "May"),  
        new ProductSales(125, 6, "June"),  
        new ProductSales(179, 7, "July"),  
        new ProductSales(170, 8, "August"),  
        new ProductSales(198, 9, "September"),  
        new ProductSales(187, 10, "October"),  
        new ProductSales(193, 11, "November"),  
        new ProductSales(212, 12, "December") 
    }; 
    return persons; 
} 
public Example() 
{ 
    InitializeComponent(); 
    this.DataContext = GetProductSales(); 
} 
Private Shared Function GetProductSales() As List(Of ProductSales) 
    Dim persons = New List(Of ProductSales)() From { 
        New ProductSales(154, 1, "January"), 
        New ProductSales(138, 2, "February"), 
        New ProductSales(143, 3, "March"), 
        New ProductSales(120, 4, "April"), 
        New ProductSales(135, 5, "May"), 
        New ProductSales(125, 6, "June"), 
        New ProductSales(179, 7, "July"), 
        New ProductSales(170, 8, "August"), 
        New ProductSales(198, 9, "September"), 
        New ProductSales(187, 10, "October"), 
        New ProductSales(193, 11, "November"), 
        New ProductSales(212, 12, "December") 
    } 
    Return persons 
End Function 
Public Sub New() 
    InitializeComponent() 
    Me.DataContext = GetProductSales() 
End Sub 

Now if we run the solution we will have a populated RadGridView control inside the RadDiagramShape. raddiagram-howto-radcontrols-gridview

We can also define a shape in the code-behind file and set its content to any RadControl. Please have a look at the example below as it demonstrates how to create a RadDiagramShape and use a RadCalendar in its Content:

public Example() 
{ 
    InitializeComponent(); 
    this.DataContext = GetProductSales(); 
    this.Loaded += this.OnLoaded; 
} 
 
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) 
{ 
    // the alternative to this code approach is to set the ContentTemplate in XAML 
    // See the documentation on this - http://www.telerik.com/help/wpf/raddiagrams-features-shapes.html 
    var calendar = new RadDiagramShape() 
    { 
        Position = new Point(20, 150), 
        Content = new RadCalendar { SelectedDate = DateTime.Now.AddDays(254), Margin = new Thickness(10) }, 
        Background = new SolidColorBrush(Colors.Blue), 
        BorderBrush = new SolidColorBrush(Colors.DarkGray), 
        BorderThickness = new Thickness(1), 
        UseGlidingConnector = true, 
        HorizontalContentAlignment = HorizontalAlignment.Stretch, 
        VerticalContentAlignment = VerticalAlignment.Stretch 
    }; 
    this.diagram.AddShape(calendar); 
} 
Public Sub New() 
    InitializeComponent() 
    Me.DataContext = GetProductSales() 
    AddHandler Me.Loaded, AddressOf Me.OnLoaded 
End Sub 
 
Private Sub OnLoaded(sender As Object, routedEventArgs As RoutedEventArgs) 
    ' the alternative to this code approach is to set the ContentTemplate in XAML ' 
    ' See the documentation on this - http://www.telerik.com/help/wpf/raddiagrams-features-shapes.html ' 
    Dim calendar = New RadDiagramShape() With { 
            .Position = New Point(20, 150), 
            .Content = New RadCalendar() With 
                        { 
                            .SelectedDate = DateTime.Now.AddDays(254), 
                            .Margin = New Thickness(10) 
                        }, 
            .Background = New SolidColorBrush(Colors.Blue), 
            .BorderBrush = New SolidColorBrush(Colors.DarkGray), 
            .BorderThickness = New Thickness(1), 
            .UseGlidingConnector = True, 
            .HorizontalContentAlignment = HorizontalAlignment.Stretch, 
            .VerticalContentAlignment = VerticalAlignment.Stretch 
    } 
    Me.diagram.AddShape(calendar) 
End Sub 

Running the project now should display two shapes within the RadDiagram instance: raddiagram-howto-radcontrols

Finally, we can connect these shapes using a single connection. Let's set it up in the OnLoaded() method implementation:

private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) 
{ 
    // the alternative to this code-approach is to set the ContentTemplate in XAML 
    // See the documentation on this, http://www.telerik.com/help/wpf/raddiagrams-features-shapes.html 
    var calendar = new RadDiagramShape() 
    { 
        //... 
    }; 
    this.diagram.AddShape(calendar); 
 
    var con = this.diagram.AddConnection(this.diagram.Shapes[1], this.diagram.Shapes[0]) as RadDiagramConnection; 
    con.Content = "Corresponds to"; 
    con.SourceCapType = CapType.Arrow6Filled; 
    con.TargetCapType = CapType.Arrow2Filled; 
} 
Private Sub OnLoaded(sender As Object, routedEventArgs As RoutedEventArgs) ' 
    ' the alternative to this code-approach is to set the ContentTemplate in XAML ' 
    ' See the documentation on this, http://www.telerik.com/help/wpf/raddiagrams-features-shapes.html 
    Dim calendar = New RadDiagramShape() From { 
                                                ... 
                                              } 
    Me.diagram.AddShape(calendar) 
 
    Dim con = TryCast(Me.diagram.AddConnection(Me.diagram.Shapes(1), Me.diagram.Shapes(0)), RadDiagramConnection) 
    con.Content = "Corresponds to" 
    con.SourceCapType = CapType.Arrow6Filled 
    con.TargetCapType = CapType.Arrow2Filled 
End Sub 

raddiagram-howto-radcontrols-link

Find a runnable project of the previous example in the WPF Samples GitHub repository.

In this article