Node Resize Template In Separate File

I have a large number of node templates all in separate files (and in a separate project), and am having a tough time figuring out how to make the resizing template available for all of my objects. I have a combined dictionary which contains other dictionaries which in-turn contain each of the node templates… how can I use an external resize template for all of my objects?

Can’t you have the resizing templates in a separate resource dictionary that is merged in before all of the others?

I’m not sure where I am going wrong…

ShapesDictionary.xaml


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/ControlObjectLibrary;component/TemplateDictionaries/NodeResizeAdornmentTemplate.xaml"/>
        <ResourceDictionary Source="pack://application:,,,/ControlObjectLibrary;component/TemplateDictionaries/Shapes/RectangleTemplate.xaml"/>
        <ResourceDictionary Source="pack://application:,,,/ControlObjectLibrary;component/TemplateDictionaries/Shapes/CircleTemplate.xaml"/>
        <ResourceDictionary Source="pack://application:,,,/ControlObjectLibrary;component/TemplateDictionaries/Shapes/TriangleTemplate.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Palette for shape objects:


<go:DataTemplateDictionary x:Key="ShapeTemplateDictionary" />
        <ResourceDictionary x:Key="ShapeDictionary" Source="pack://application:,,,/ControlObjectLibrary;component/TemplateDictionaries/Shapes/ShapesDictionary.xaml"/>


<go:Palette x:Name="shapePalette"
                            Padding="5"
                            Loaded="palette_Loaded"
                            NodeTemplateDictionary="{DynamicResource ShapeTemplateDictionary}"
                            UnloadingClearsPartManager="False"
                            MaximumSelectionCount="1" />

And in code-behind:


var shapepalettemodel = new MyModel() { NodesSource = nodeLib.ShapeNodes };
            ResourceDictionary shapeDictionary = FindResource<ResourceDictionary>(this, "ShapeDictionary");
            var shapeTemplates = FindResource<DataTemplateDictionary>(this, "ShapeTemplateDictionary");
            insertNodeTemplates(shapeDictionary, shapeTemplates);
            this.shapePalette.Model = shapepalettemodel;

Any insight as to what I might be missing?

The resizing template appears to be added to the dictionary that is used as the NodeSourceDictionary, but the actual template that shows up on my objects in the drawing is still the default template.

So, how do you set the go.Part:ResizeAdornmentTemplate in one of your node DataTemplates?


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:go="http://schemas.nwoods.com/GoXam"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <go:BooleanBrushConverter x:Key="theStrokeChooser" TrueBrush="Red" FalseBrush="Transparent" />
    <go:BooleanBrushConverter x:Key="backgroundChooser" TrueBrush="White" FalseBrush="Transparent" />
    <go:BooleanThicknessConverter x:Key="strokeThicknessChooser" TrueThickness="0" FalseThickness="1" />
    
    <DataTemplate x:Key="Triangle">
        <Grid
            go:Part.SelectionAdorned="True"
            go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
            go:Node.LocationSpot="Center"
            go:Part.Resizable="{Binding Path=Data.Resizable, Mode=OneTime}"
            go:Part.ResizeElementName="Container"
            go:Part.ResizeAdornmentTemplate="{DynamicResource NodeResizeAdornmentTemplate}"
            go:Part.Rotatable="{Binding Path=Data.Rotatable, Mode=OneTime}"
            go:Node.RotationAngle="{Binding Path=Data.Angle, Mode=TwoWay}"
            go:Part.Reshapable="False">

            <go:NodePanel>
                <go:NodeShape Name="Container" 
                              go:NodePanel.Figure="Triangle"
                              Stroke="Black" StrokeThickness="1"
                              Fill="White"
                              go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1"
                              Height="{Binding Path=Data.Height, Mode=TwoWay}"
                              Width="{Binding Path=Data.Width, Mode=TwoWay}" />
                
                <Rectangle Fill="Transparent" Margin="13" Cursor="SizeAll" />
                
                <TextBlock Text="{Binding Path=Data.Text, Mode=TwoWay}" TextWrapping="Wrap" Background="White"
                           HorizontalAlignment="Center" VerticalAlignment="Center"
                           go:Part.TextEditable="True" Cursor="IBeam" />
            </go:NodePanel>
        </Grid>
    </DataTemplate>
</ResourceDictionary>

I don’t know.

If you call FindResource(“NodeResizeAdornmentTemplate”), do you get the DataTemplate defined in that XAML file?

I tried moving the resize template to the same XAML file as my diagram, and can confirm that FindResource(this, “NodeResizeAdornmentTemplate”) does find the template. To make sure, I added an event handler to add the template to the node when it is dropped on the diagram, which does give me the right template.


public DiagramPane()
{
      ...

      resizeTemplate = FindResource<DataTemplate>(this, "NodeResizeAdornmentTemplate");
      myDiagram.ExternalObjectsDropped += drop;

      ...
}

private void drop(object sender, RoutedEventArgs e)
{
      myDiagram.SelectedNode.ResizeAdornmentTemplate = resizeTemplate;
}

Having the template added this way is what I am trying to avoid, because if the node is deleted and then brought back via undo/redo, the resize template is no longer on the node.

Particularly since you’re using DynamicResource, I would think it should be OK, even if it might fail with StaticResource.
So I don’t understand what the problem is.

Unless maybe it’s just a typo or some other simple error.