Set primary node in Selected nodes

How can a node be selected as primary node in a group of selected nodes. I am after the sort of functionality as in Visual Studio Windows forms designer where if multiple controls are selected then one of them has white selection grip and rest have black selection grip, control with white grips is the primary selected control and all alignment and sizing actions are executed based on the location and size of primary selected control.

There already is a notion of the primary selection: the Diagram.SelectedPart.

However, the standard selection template and tool templates (such as for resizing handles) don’t distinguish between them. The standard tools also don’t operate on multiple parts if they would normally just work on a single part.

You’ll need to do two things: provide customization of the selection and tool templates based on whether the part is the primary selection, and customize the tools and commands to work on multiple parts when modifying the primary selection.

I believe you might be able to do the former by defining a converter that takes a Part and returns one Brush if it’s the Diagram.SelectedPart and returns a different Brush otherwise. Then you can adapt the standard selection and tool templates by using this converter. (You can find the standard templates in Generic…XAML in the docs subdirectory of the installation. Some of the samples also demonstrate customizing selection and tool templates.)

You might need a second converter that returns a boolean or some other kind of value based on whether the part is the primary selection, to customize properties other than the color.

For the second task, you’ll need to customize the tools that you care about by overriding methods such as ResizingTool.DoResize to also resize the secondary selections.

I need the Primary object just for Alignment purposes only (had mentioned resizing for an example only).



I have customised the SelectionAdornmentTemplate as follows

<br /><DataTemplate x:Key="PrimarySelectionTemplate"> <br /> <go:SelectionHandle Stroke="{Binding Path=., <br /> RelativeSource={RelativeSource AncestorType={x:Type go:Part}}, <br /> Mode=TwoWay, <br /> Converter={StaticResource PrimSelectionColorCoonveter}}" <br /> StrokeThickness="3" <br /> go:Part.Selectable="False" <br /> SnapsToDevicePixels="True" /> <br /> </DataTemplate> <br />

In the converter I do the following

<br />public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) <br /> { <br /> Adornment adr = value as Adornment; <br /> if (adr != null && adr.Diagram !=null && adr.AdornedPart != null && adr.AdornedPart == adr.Diagram.SelectedPart) <br /> { <br /> return Brushes.Green; <br /> } <br /> <br /> return Brushes.Red; <br /> } <br />



It does what I need but just wondering if this the optimum way of doing it or can I improve it in some way

That’s fine.

I suppose you could replace the “Path=., RelativeSource=…” with “Path=Part”. (This would work in Silverlight, too, since Silverlight doesn’t support RelativeSource.)

Or you could use “Path=Part.AdornedPart” and change the converter to take the AdornedPart instead of just the Adornment. I think that would be even simpler.

Caution: I haven’t actually tested either alternative in your scenario.