I've figured out almost all of the issues I was having. I wish I could attach the sample project, but I can't here. I've included the main code below.
Fixed Copy/Paste of Shape by using Caliburn.Micro's ViewLocator in IsItemItsOwnShapeContainerOverride of derived RadDiagram.
This means that UserControl cannot be used (easily) because you must inherit from RadDiagramShapeBase to get IShape contract. Alternatively, you could implment IShape, etc in the UserControl (not practical).
The RadDiagramShape style override in the Themes\Generic.xaml that uses Caliburn.Micro's View/ViewModel binding solves the issue I thought I'd have with multiple custom shapes.
Unless I'm mistaken, it appears that you really can't use a UserControl to separate the shape views as you must inherit from RadDiagramShapeBase to make the whole thing work. I don't like this from an "ease of design-time" point-of-view, but, at least, everything can be cleanly separated, which is good. I guess you can edit the Template in Blend using the Styles approach, but it makes things more tedious when trying to use the Visual Studio designer...
Thoughts?
MyRadDiagram.cs:
Fixed Copy/Paste of Shape by using Caliburn.Micro's ViewLocator in IsItemItsOwnShapeContainerOverride of derived RadDiagram.
This means that UserControl cannot be used (easily) because you must inherit from RadDiagramShapeBase to get IShape contract. Alternatively, you could implment IShape, etc in the UserControl (not practical).
The RadDiagramShape style override in the Themes\Generic.xaml that uses Caliburn.Micro's View/ViewModel binding solves the issue I thought I'd have with multiple custom shapes.
Unless I'm mistaken, it appears that you really can't use a UserControl to separate the shape views as you must inherit from RadDiagramShapeBase to make the whole thing work. I don't like this from an "ease of design-time" point-of-view, but, at least, everything can be cleanly separated, which is good. I guess you can edit the Template in Blend using the Styles approach, but it makes things more tedious when trying to use the Visual Studio designer...
Thoughts?
MyRadDiagram.cs:
using Caliburn.Micro;
using Telerik.Windows.Controls;
using Telerik.Windows.Diagrams.Core;
namespace DiagramTests.CustomControls
{
public class MyRadDiagram : RadDiagram
{
protected override IShape GetShapeContainerForItemOverride(object item)
{
var shapeContainer = ViewLocator.LocateForModel(item, this, null) as IShape;
return shapeContainer;
}
}
}
Themes\Generic.xaml:<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
xmlns:t="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Diagrams">
<!-- Change ControlTemplate of RadDiagramShape to whatever Caliburn.Micro-->
<!-- resolves as the View for the ViewModel -->
<Style TargetType="t:RadDiagramShape">
<Setter Property="Position" Value="{Binding Position, Mode=TwoWay}"></Setter>
<Setter Property="RotationAngle" Value="{Binding RotationAngle, Mode=TwoWay}"></Setter>
<Setter Property="Height" Value="{Binding Height, Mode=TwoWay}"></Setter>
<Setter Property="Width" Value="{Binding Width, Mode=TwoWay}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentControl cal:View.Model="{Binding}"></ContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
DesignerCanvasViewModel.csusing System.ComponentModel.Composition;
using System.Windows;
using Telerik.Windows.Controls.Diagrams.Extensions.ViewModels;
namespace DiagramTests.ViewModels
{
[Export(typeof (DesignerCanvasViewModel))]
public class DesignerCanvasViewModel :
ObservableGraphSourceBase<NodeViewModelBase, LinkViewModelBase<NodeViewModelBase>>
{
public DesignerCanvasViewModel()
{
this.AddNodesUsingDerived();
}
private void AddNodesUsingDerived()
{
this.AddNode(new MyCustomShapeViewModel
{
Position = new Point(10, 10)
});
this.AddNode(new MyCustomShapeViewModel
{
Position = new Point(10, 70)
});
this.AddNode(new MyRadioControlShapeViewModel
{
Position = new Point(10, 150)
});
}
}
}
App.xaml<Application x:Class="DiagramTests.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:DiagramTests.Infrastructure">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources\Brushes.xaml"></ResourceDictionary>
<ResourceDictionary Source="Themes\Generic.xaml"></ResourceDictionary>
<ResourceDictionary Source="Views\MyRadioControlShapeStyle.xaml"></ResourceDictionary>
<ResourceDictionary>
<my:CaliburnBootstrapper x:Key="bootstrapper" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MyRadioControlShape.csusing Telerik.Windows.Controls.Diagrams;
namespace DiagramTests.Views
{
public class MyRadioControlShape : RadDiagramShapeBase {}
}
MyRadioControlShapeStyle.xaml<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:DiagramTests.Views"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable="d">
<Style TargetType="{x:Type views:MyRadioControlShape}">
<Setter Property="BorderThickness" Value="4" />
<Setter Property="BorderBrush" Value="#6C666666" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="Auto" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Margin" Value="0" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" />
<GradientStop Offset="1" Color="#FFEDF4FF" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type views:MyRadioControlShape}">
<Border Margin="{TemplateBinding Margin}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3" d:DesignWidth="253.333" d:DesignHeight="160.667">
<Border Background="{TemplateBinding Background}"
BorderBrush="#E6FBFDFF"
BorderThickness="1"
CornerRadius="1">
<StackPanel>
<Grid Margin="40 5" VerticalAlignment="Center">
<TextBlock FontFamily="Segoe UI"
FontSize="14"
Text="MIX RADIO" />
<TextBlock HorizontalAlignment="Right"
FontFamily="Segoe UI"
FontSize="14"
Text="108.8 FM" />
</Grid>
<Border Height="80"
BorderBrush="#6C666666"
BorderThickness="0 1">
<Border.Background>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#65FFFFFF" />
<GradientStop Offset="0.965" Color="#66E7E5E5" />
<GradientStop Offset="0.609" Color="#9DD9D9D9" />
<GradientStop Offset="0.826" Color="#A5D9D9D9" />
</LinearGradientBrush>
</Border.Background>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock x:Name="BufferingPercentageLabel"
Margin="0 0 0 15"
HorizontalAlignment="Center"
FontFamily="Segoe UI"
FontSize="13">
<TextBlock.Foreground>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="1" Color="Black" />
<GradientStop Color="#FF727272" />
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
<telerik:RadProgressBar x:Name="BufferingProgressBar"
Width="270"
Height="30"
Maximum="100"
Minimum="0"
Value="60" />
</StackPanel>
</Border>
<Border Padding="0 5">
<Border.Background>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0.07" Color="#7FFFFFFF" />
<GradientStop Offset="0.965" Color="#7EE7E5E5" />
<GradientStop Offset="0.61" Color="#FFD9D9D9" />
<GradientStop Offset="0.826" Color="#FFD9D9D9" />
</LinearGradientBrush>
</Border.Background>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<TextBlock Margin="0 0 0 15"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Segoe UI"
FontSize="13"
Text="VOTE">
<TextBlock.Foreground>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="1" Color="Black" />
<GradientStop Color="#FF727272" />
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
<telerik:RadRating x:Name="Rating"
Margin="15 0"
HorizontalAlignment="Center"
Value="3" />
</StackPanel>
</Border>
</StackPanel>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
CaliburnBootstrapper.csusing...
namespace DiagramTests.Infrastructure
{
public class CaliburnBootstrapper : Bootstrapper<ShellViewModel>
{
private CompositionContainer container;
protected override void Configure()
{
ViewLocator.AddDefaultTypeMapping("Shape");
ViewModelLocator.AddDefaultTypeMapping("Shape");
...