We have two views (graphical windows, i.e. plugins) that are synchronized. They both show the same data in a different manner.One view displays the data in grid form, the ohter in tree form, which I just switched over from Microsoft WPF to IG XamDataTree.
When I click on a row in the grid-view, it sends a C# event to the tree-view to select the corresponding item.The tree-view receives the event, finds the corresponding view-model item, and sets a bound property equal to this found item, effectively selecting the correct XamDataTreeNode.
However, the keyboard focus is not set to the tree-view although I was scrrolling in the grid-view!!
Our XamDataTree is a custom one, that I located in an IG forum. Here it is (with very slight mods):
//--------------------------------------------------------------------public class RsCustomIgTreeView : XamDataTree{ private static XamDataTreeNodesCollection msNodes; public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register( "SelectedItem", typeof(object), typeof(RsCustomIgTreeView), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, OnPropertyChangedCallback)); public static void OnPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { FindCorrespondingNode(msNodes, e.NewValue); } public RsCustomIgTreeView() { ActiveNodeChanged += OnActiveNodeChanged; msNodes = Nodes;
AddHandler(PreviewGotKeyboardFocusEvent, (RoutedEventHandler)OnPreviewGotKeyboardFocusEvent, true); } private static void OnPreviewGotKeyboardFocusEvent(object sender, RoutedEventArgs e) { var treeView = sender as RsCustomIgTreeView; if (treeView == null) return; var viewModelBase = treeView.DataContext as ViewModelBase; if (viewModelBase == null) return; if (!viewModelBase.IsActive) e.Handled = true; } void OnActiveNodeChanged(object sender, ActiveNodeChangedEventArgs e) { if (e.NewActiveTreeNode != null) { SelectedItem = e.NewActiveTreeNode.Data; } } public object SelectedItem { get { return GetValue(SelectedItemsProperty); } set { SetValue(SelectedItemsProperty, value); } } private static void FindCorrespondingNode(XamDataTreeNodesCollection nodes, object value) { foreach (XamDataTreeNode node in nodes) { if (node.Data.Equals(value)) { node.IsActive = true; node.IsSelected = true; return; } if (node.HasChildren) { FindCorrespondingNode(node.Nodes, value); } } }}//--------------------------------------------------------------------
--> The fix was the event-handler "OnPreviewGotKeyboardFocusEvent", see above. Why is this necessary? Do all IG components have this behavior?
Thanks,Mark
Hello Mark,
Thank you for your post. I have been looking through it and I can say that this is normal, because our controls doesn’t fire their events if the action is done by code. If so, you can execute the desired code after the action you perform. This is like a pattern for custom controls, which is used to have better performance.
Hope this helps you.
Hello again!I believe I made a small error in the description of the problem. I said:
"However, the keyboard focus is not set to the tree-view although I was scrrolling in the grid-view!!"But what I meant was:However, the keyboard focus is now set to the tree-view although I was scrrolling in the grid-view!!
To re-phrase the question: 1) Why, when I programatically set the selected element in my VIEW-MODEL, which is bound to the view, does the XamDataTree steal the keyboard focus?In the standard Microsoft WPF TreeView, this is not the case.
2) Given that this is the case, HOW CAN I PREVENT OR OTHERWISE COMPENSATE FOR THIS UNDESIRED BEHAVIOR?
Kindest Regards,Mark Horowitz
I can say that this behaviour occurs by design and it is achieved using code, so I believe that the approach you use with the OnPreviewGetKeyboardFocus is the best one for achieving the result you want, but if I think of a better one I will let you know.