1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public static class TreeViewBehavior
{
#region ExpandedCommand
public static DependencyProperty ExpandedCommandProperty =
DependencyProperty.RegisterAttached
(
"ExpandedCommand",
typeof(ICommand),
typeof(TreeViewBehavior),
new UIPropertyMetadata(ExpandedCommandChanged)
);
private static void ExpandedCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
var element = target as TreeView;
if (element == null) throw new InvalidOperationException("This behavior can be attached to TreeView only.");
if (e.OldValue != null && e.NewValue == null)
{
element.RemoveHandler(TreeViewItem.ExpandedEvent, new RoutedEventHandler(Expanded));
element.RemoveHandler(UIElement.PreviewMouseLeftButtonDownEvent, new RoutedEventHandler(Expanded));
element.RemoveHandler(UIElement.PreviewMouseUpEvent, new RoutedEventHandler(Expanded));
}
if (e.OldValue == null && e.NewValue != null)
{
element.AddHandler(TreeViewItem.ExpandedEvent, new RoutedEventHandler(Expanded));
element.AddHandler(UIElement.PreviewMouseLeftButtonDownEvent, new RoutedEventHandler(Expanded));
element.AddHandler(UIElement.PreviewMouseUpEvent, new RoutedEventHandler(Expanded));
}
}
static Cursor _waitCursor = new Cursor(ResourceHelper.GetStream("Images/loading.ani", "Theme"));
static void Expanded(object sender, RoutedEventArgs e)
{
var treeview = sender as TreeView;
if (treeview == null)
return;
TreeViewItem sourceItem = e.OriginalSource as TreeViewItem;
if ((sourceItem != null)
&& (sourceItem.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated))
{
// create a handler that will check our children and reset the cursor when the ItemContainerGenerator has finished
EventHandler itemsGenerated = null;
itemsGenerated = delegate(object o, EventArgs args)
{
// if the children are done being generated...
if (((ItemContainerGenerator)o).Status == GeneratorStatus.ContainersGenerated)
{
((ItemContainerGenerator)o).StatusChanged -= itemsGenerated; // we're done, so remove the handler
sourceItem.Dispatcher.BeginInvoke(DispatcherPriority.DataBind, (ThreadStart)delegate // asynchronous reset of cursor
{
var window = Window.GetWindow(treeview);
treeview.Cursor = window != null ? window.Cursor : Cursors.Arrow;
});
}
};
sourceItem.ItemContainerGenerator.StatusChanged += itemsGenerated; // add the handler
treeview.Cursor = _waitCursor;
}
var command = (ICommand)treeview.GetValue(ExpandedCommandProperty);
if (command.CanExecute(true))
{
command.Execute(treeview.SelectedItem);
}
}
#endregion
} |
Partager