Binding selection to model

I have a diagram that is part of a larger application. Data can be displayed on multiple views simultaneously. Selecting the data in one view should select it in all views. Thus there’s an external selection manager component that handles all of this notification.

What this means for my diagram is that I need some way of having the diagram both react to this external selection as well as publish it’s selection changes out to the selection manager. One approach would be to shove this information into my model classes (I’m deriving from GraphLinksModelNodeData and GraphLinksModelLinksData) and then simply bind Part.IsSelected up to the model. But this leads to a few questions:

  1. How can I make this binding in XAML? For example, I see that I can make my own PartManager, override MakeLinkForData, and then create a binding in code at that point. However, I’d really prefer to have all my bindings in XAML. Is this possible through the LinkDataTemplate? Do I need to derive from Link (not clear how I’d create the binding in XAML)?

  2. Is it a bad idea to store this information in the model? For example, I see that the ClickSelectingTool notes that it does not edit the model, but I’d be changing those tool semantics. I don’t know if this is an issue.

  3. Is there a better way to approach this problem in GoXam? I don’t have a need to store the selection data in the model, it just seemed like a convenient place to which I could later data bind. However, this piece of data is not something which I need to serialize/deserialize. If I were to react to external selection events and not store this information, it’s not clear to me how I could easily go from a unique NodeKey value to a particular Part.

I think you could do it either way, but you’re right that “transient” state cannot be bound to data easily in XAML. And I suspect that you are right, that selection information really doesn’t belong in your model. So I do suggest you go with the event-handling in-memory approach.

You might find this useful: EntityRelationship sample and synchronizing selection in multiple controls

Thanks for the pointer, that was a great start. However, it’s not clear how I should use PartManager.FindPartsForData(). Specifically, I’m stuck on how I should create the IDataCollection. (All of the online help links for GraphLinksModel.DataCollection are giving HTTP 404. This applies to both WPF and Silverlight documentation.)

Do I just do something like this:

var collection = Diagram.Model.CreateDataCollection();
foreach (var node in ExternalSelection)
<span =“Apple-tab-span” style=“white-space:pre”> collection.AddNode(node);
foreach (var link in ExternalSelection)
<span =“Apple-tab-span” style=“white-space:pre”> collection.AddLink(link);
var parts = Diagram.PartManager.FindPartsForData(collection);
Diagram.Select(parts);

Thanks for noting the 404 errors. We just moved to a new server, and maybe something got messed up along the way.

Here’s the code from the Entity Relationship sample in version 1.3:

[code] // Synchronized selection support

private void myListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
  UpdateSelection(e.AddedItems.OfType<Entity>().FirstOrDefault());
}

private void myDiagram_SelectionChanged(object sender, SelectionChangedEventArgs e) {
  UpdateSelection(e.AddedItems.OfType<Node>().Select(n => n.Data).FirstOrDefault());
}

private void UpdateSelection(Object data) {
  // protect against recursive selection changing behavior,
  // especially if there are more than two controls to keep in sync
  if (this.ChangingSelection) return;
  this.ChangingSelection = true;

  myListBox.SelectedItem = data;
  myListBox.ScrollIntoView(data);

  Node node = myDiagram.PartManager.FindNodeForData(data, myDiagram.Model);
  if (node != null) myDiagram.Select(node);

  this.ChangingSelection = false;
}

private bool ChangingSelection { get; set; }[/code]

I assume the issue for you is that you want to maintain multiple selection, not just a single selection. If so, then what you suggest looks good to me.