I've got a WPF application with a Treeview control.
When the user clicks a node on the tree, other TextBox, ComboBox, etc. controls on the page are populated with appropriate values.
The user can then make changes to those values and save his or her changes by clicking a Save button.
However, if the user selects a different Treeview node without saving his or her changes, I want to display a warning and an opportunity to cancel that selection.
XAML...
<TreeView Name="TreeViewThings"
...
TreeViewItem.Unselected="TreeViewThings_Unselected"
TreeViewItem.Selected="TreeViewThings_Selected" >
Visual Basic...
Sub TreeViewThings_Unselected(ByVal sender As System.Object, _ ByVal e As System.Windows.RoutedEventArgs) Dim OldThing As Thing = DirectCast(e.OriginalSource.DataContext, Thing) If CancelDueToUnsavedChanges(OldThing) Then 'put canceling code here End If End Sub Sub TreeViewThings_Selected(ByVal sender As System.Object, _ ByVal e As System.Windows.RoutedEventArgs) Dim NewThing As Thing = DirectCast(e.OriginalSource.DataContext, Thing) PopulateControlsFromThing(NewThing) End Sub
How can I cancel those unselect/select events?
Update: I've asked a follow-up question...
How do I properly handle a PreviewMouseDown event with a MessageBox confirmation?
UPDATE
Realized I could put the logic in SelectedItemChanged instead. A little cleaner solution.
Xaml
Code behind. I have some classes that is my ItemsSource of the TreeView so I made an interface (MyInterface) that exposes the IsSelected property for all of them.
I haven't found any situation where it doesn't revert back to the previous item upon pressing "No".
I had to solve the same problem, but in multiple treeviews in my application. I derived TreeView and added event handlers, partly using Meleak's solution and partly using the extension methods from this forum: http://forums.silverlight.net/t/65277.aspx/1/10
I thought I'd share my solution with you, so here is my complete reusable TreeView that handles "cancel node change":
Here is an example of usage (codebehind for window containing a MyTreeView):
After choosing the first node in the treeview, all other node changes are cancelled and a message box is displayed.
Instead of selecting for Selected/Unselected, a better route might be to hook into PreviewMouseDown. The preblem with handling a Selected and Unselected event is that the event has already occurred when you receive the notification. There is nothing to cancel because it's already happened.
On the other hand, Preview events are cancelable. It's not the exact event you want but it does give you the oppuritunity to prevent the user from selecting a different node.
Since the
SelectedItemChanged
event is triggered after theSelectedItem
has already changed, you can't really cancel the event at this point.What you can do is listen for mouse-clicks and cancel them before the
SelectedItem
gets changed.You can't actually put your logic into the OnSelectedItemChanged Method, if the logic is there the Selected Item has actually already changed.
As suggested by another poster, the PreviewMouseDown handler is a better spot to implement the logic, however, a fair amount of leg work still needs to be done.
Below is my 2 cents:
First the TreeView that I have implemented:
some extension methods to support the TreeView finding the object under the mouse.
and last, but not least the custom EventArgs that leverage the RoutedEvent subsystem.
CAMS_ARIES:
XAML:
code :