Browse Source

ICSharpCode.TreeView: improve API for drag/drop/copy/paste of nodes.

newNR
Daniel Grunwald 12 years ago
parent
commit
f27a7426b2
  1. 35
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs
  2. 17
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
  3. 10
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs
  4. 21
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs
  5. 19
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs
  6. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs
  7. 15
      src/Libraries/SharpTreeView/ICSharpCode.TreeView.Demo/FileNode.cs
  8. 42
      src/Libraries/SharpTreeView/ICSharpCode.TreeView.Demo/FileSystemNode.cs
  9. 34
      src/Libraries/SharpTreeView/ICSharpCode.TreeView.Demo/FolderNode.cs
  10. 102
      src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeNode.cs
  11. 7
      src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeNodeView.cs
  12. 68
      src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs
  13. 4
      src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeViewItem.cs

35
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs

@ -36,22 +36,12 @@ namespace ICSharpCode.XamlBinding @@ -36,22 +36,12 @@ namespace ICSharpCode.XamlBinding
public ITextAnchor EndMarker { get; set; }
public ITextEditor Editor { get; set; }
public override bool CanDrag(SharpTreeNode[] nodes)
{
return false; //nodes.All(node => node.Parent != null);
}
public override bool CanDrop(DragEventArgs e, int index)
{
return false;
}
public string GetMarkupText()
{
return Editor.Document.GetText(Marker.Offset, EndMarker.Offset - Marker.Offset);
}
public override IDataObject Copy(SharpTreeNode[] nodes)
protected override IDataObject GetDataObject(SharpTreeNode[] nodes)
{
string[] data = nodes
.OfType<XamlOutlineNode>()
@ -63,11 +53,6 @@ namespace ICSharpCode.XamlBinding @@ -63,11 +53,6 @@ namespace ICSharpCode.XamlBinding
return dataObject;
}
public override bool CanDelete()
{
return Parent != null;
}
// public override void Drop(IDataObject data, int index, DropEffect finalEffect)
// {
// try {
@ -96,12 +81,24 @@ namespace ICSharpCode.XamlBinding @@ -96,12 +81,24 @@ namespace ICSharpCode.XamlBinding
// }
// }
public override void Delete()
public override bool CanDelete(SharpTreeNode[] nodes)
{
return nodes.OfType<XamlOutlineNode>().All(n => n.Parent != null);
}
public override void Delete(SharpTreeNode[] nodes)
{
DeleteCore();
DeleteWithoutConfirmation(nodes);
}
public override void DeleteWithoutConfirmation(SharpTreeNode[] nodes)
{
foreach (XamlOutlineNode xamlNode in nodes.OfType<XamlOutlineNode>()) {
xamlNode.DeleteCore();
}
}
public override void DeleteCore()
void DeleteCore()
{
Editor.Document.Remove(Marker.Offset, EndMarker.Offset - Marker.Offset);
}

17
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs

@ -132,29 +132,20 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -132,29 +132,20 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
class WatchRootNode : SharpTreeNode
{
public override bool CanDrop(DragEventArgs e, int index)
public override bool CanPaste(IDataObject data)
{
e.Effects = DragDropEffects.None;
if (e.Data.GetDataPresent(DataFormats.StringFormat)) {
e.Effects = DragDropEffects.Copy;
return true;
}
return false;
return data.GetDataPresent(DataFormats.StringFormat);
}
public override void Drop(DragEventArgs e, int index)
public override void Paste(IDataObject data)
{
if (e.Data == null) return;
if (!e.Data.GetDataPresent(DataFormats.StringFormat)) return;
var watchValue = e.Data.GetData(DataFormats.StringFormat).ToString();
var watchValue = data.GetData(DataFormats.StringFormat) as string;
if (string.IsNullOrEmpty(watchValue)) return;
var pad = SD.Workbench.GetPad(typeof(WatchPad)).PadContent as WatchPad;
if (pad == null) return;
pad.AddWatch(watchValue);
WindowsDebugger.RefreshPads();
}
}

10
src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs

@ -35,14 +35,16 @@ namespace Debugger.AddIn.Pads.Controls @@ -35,14 +35,16 @@ namespace Debugger.AddIn.Pads.Controls
get { return this.Node.GetChildren != null; }
}
public override bool CanDelete()
public override bool CanDelete(SharpTreeNode[] nodes)
{
return this.Node.CanDelete;
return nodes.All(n => n is SharpTreeNodeAdapter)
&& nodes.Cast<SharpTreeNodeAdapter>().All(n => n.Node.CanDelete);
}
public override void Delete()
public override void Delete(SharpTreeNode[] nodes)
{
Parent.Children.Remove(this);
foreach (var node in nodes)
node.Parent.Children.Remove(this);
}
protected override void LoadChildren()

21
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs

@ -158,19 +158,24 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -158,19 +158,24 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int endOffset = i + 1 < stateChangeOffsets.Length ? stateChangeOffsets[i + 1] : text.Length;
Run r = new Run(text.Substring(startOffset, endOffset - startOffset));
HighlightingColor state = stateChanges[i];
if (state.Foreground != null)
r.Foreground = state.Foreground.GetBrush(null);
if (state.Background != null)
r.Background = state.Background.GetBrush(null);
if (state.FontWeight != null)
r.FontWeight = state.FontWeight.Value;
if (state.FontStyle != null)
r.FontStyle = state.FontStyle.Value;
ApplyColorToTextElement(r, state);
runs[i] = r;
}
return runs;
}
internal static void ApplyColorToTextElement(TextElement r, HighlightingColor state)
{
if (state.Foreground != null)
r.Foreground = state.Foreground.GetBrush(null);
if (state.Background != null)
r.Background = state.Background.GetBrush(null);
if (state.FontWeight != null)
r.FontWeight = state.FontWeight.Value;
if (state.FontStyle != null)
r.FontStyle = state.FontStyle.Value;
}
/// <summary>
/// Produces HTML code for the line, with &lt;span style="..."&gt; tags.
/// </summary>

19
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs

@ -7,6 +7,7 @@ using System.Collections.Generic; @@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -264,5 +265,23 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -264,5 +265,23 @@ namespace ICSharpCode.AvalonEdit.Highlighting
index++;
}
}
/// <summary>
/// Creates WPF Run instances that can be used for TextBlock.Inlines.
/// </summary>
/// <param name="textSource">The text source that holds the text for this RichTextModel.</param>
public Run[] CreateRuns(ITextSource textSource)
{
Run[] runs = new Run[stateChanges.Count];
for (int i = 0; i < runs.Length; i++) {
int startOffset = stateChangeOffsets[i];
int endOffset = i + 1 < stateChangeOffsets.Count ? stateChangeOffsets[i + 1] : textSource.TextLength;
Run r = new Run(textSource.GetText(startOffset, endOffset - startOffset));
HighlightingColor state = stateChanges[i];
RichText.ApplyColorToTextElement(r, state);
runs[i] = r;
}
return runs;
}
}
}

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs

@ -9,6 +9,9 @@ using ICSharpCode.AvalonEdit.Highlighting; @@ -9,6 +9,9 @@ using ICSharpCode.AvalonEdit.Highlighting;
namespace ICSharpCode.AvalonEdit.Utils
{
// TODO: This class (and derived classes) is currently unused; decide whether to keep it.
// (until this is decided, keep the class internal)
/// <summary>
/// A text writer that supports creating spans of highlighted text.
/// </summary>

15
src/Libraries/SharpTreeView/ICSharpCode.TreeView.Demo/FileNode.cs

@ -84,10 +84,15 @@ namespace ICSharpCode.TreeView.Demo @@ -84,10 +84,15 @@ namespace ICSharpCode.TreeView.Demo
{
get { return info.FullName; }
}
//
// public override void Paste(IDataObject data)
// {
// Parent.Paste(data);
// }
public override bool CanPaste(IDataObject data)
{
return Parent.CanPaste(data);
}
public override void Paste(IDataObject data)
{
Parent.Paste(data);
}
}
}

42
src/Libraries/SharpTreeView/ICSharpCode.TreeView.Demo/FileSystemNode.cs

@ -29,46 +29,40 @@ namespace ICSharpCode.TreeView.Demo @@ -29,46 +29,40 @@ namespace ICSharpCode.TreeView.Demo
{
return FullPath;
}
//
// public override bool CanCopy(SharpTreeNode[] nodes)
// {
// return true;
// }
public override IDataObject Copy(SharpTreeNode[] nodes)
public override bool CanCopy(SharpTreeNode[] nodes)
{
return nodes.All(n => n is FileSystemNode);
}
protected override IDataObject GetDataObject(SharpTreeNode[] nodes)
{
var data = new DataObject();
var paths = nodes.OfType<FileSystemNode>().Select(n => n.FullPath).ToArray();
data.SetData(typeof(string[]), paths);
data.SetData(DataFormats.FileDrop, paths);
return data;
}
//
// public override bool CanPaste(IDataObject data)
// {
// return true;
// }
//
public override bool CanDelete()
public override bool CanDelete(SharpTreeNode[] nodes)
{
return true;
return nodes.All(n => n is FileSystemNode);
}
public override void Delete()
public override void Delete(SharpTreeNode[] nodes)
{
if (MessageBox.Show("Sure?", "Delete", MessageBoxButton.OKCancel) == MessageBoxResult.OK) {
DeleteCore();
if (MessageBox.Show("Are you sure you want to delete " + nodes.Length + " items?", "Delete", MessageBoxButton.OKCancel) == MessageBoxResult.OK) {
DeleteWithoutConfirmation(nodes);
}
}
public override void DeleteCore()
public override void DeleteWithoutConfirmation(SharpTreeNode[] nodes)
{
this.Parent.Children.Remove(this);
foreach (var node in nodes) {
if (node.Parent != null)
node.Parent.Children.Remove(node);
}
}
public override bool CanDrag(SharpTreeNode[] nodes)
{
return true;
}
// ContextMenu menu;
//

34
src/Libraries/SharpTreeView/ICSharpCode.TreeView.Demo/FolderNode.cs

@ -63,11 +63,11 @@ namespace ICSharpCode.TreeView.Demo @@ -63,11 +63,11 @@ namespace ICSharpCode.TreeView.Demo
{
try {
foreach (var p in Directory.GetDirectories(path)
.OrderBy(d => Path.GetDirectoryName(d))) {
.OrderBy(d => Path.GetDirectoryName(d))) {
Children.Add(new FolderNode(p));
}
foreach (var p in Directory.GetFiles(path)
.OrderBy(f => Path.GetFileName(f))) {
.OrderBy(f => Path.GetFileName(f))) {
Children.Add(new FileNode(p));
}
}
@ -75,22 +75,34 @@ namespace ICSharpCode.TreeView.Demo @@ -75,22 +75,34 @@ namespace ICSharpCode.TreeView.Demo
}
}
public override bool CanDrop(DragEventArgs e, int index)
public override bool CanPaste(IDataObject data)
{
return e.Data.GetDataPresent(typeof(string[]));
return data.GetDataPresent(DataFormats.FileDrop);
}
public override void Drop(DragEventArgs e, int index)
public override void Paste(IDataObject data)
{
var paths = e.Data.GetData(typeof(string[])) as string[];
var paths = data.GetData(DataFormats.FileDrop) as string[];
if (paths != null) {
for (int i = 0; i < paths.Length; i++) {
var p = paths[i];
foreach (var p in paths) {
if (File.Exists(p)) {
Children.Insert(index + i, new FileNode(p));
Children.Add(new FileNode(p));
} else {
Children.Add(new FolderNode(p));
}
else {
Children.Insert(index + i, new FolderNode(p));
}
}
}
public override void Drop(DragEventArgs e, int index)
{
var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
if (paths != null) {
foreach (var p in paths) {
if (File.Exists(p)) {
Children.Insert(index++, new FileNode(p));
} else {
Children.Insert(index++, new FolderNode(p));
}
}
}

102
src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeNode.cs

@ -441,7 +441,10 @@ namespace ICSharpCode.TreeView @@ -441,7 +441,10 @@ namespace ICSharpCode.TreeView
#region Cut / Copy / Paste / Delete
public bool IsCut { get { return false; } }
/// <summary>
/// Gets whether the node should render transparently because it is 'cut' (but not actually removed yet).
/// </summary>
public virtual bool IsCut { get { return false; } }
/*
static List<SharpTreeNode> cuttedNodes = new List<SharpTreeNode>();
static IDataObject cuttedData;
@ -538,66 +541,99 @@ namespace ICSharpCode.TreeView @@ -538,66 +541,99 @@ namespace ICSharpCode.TreeView
}
*/
public virtual bool CanDelete()
public virtual bool CanDelete(SharpTreeNode[] nodes)
{
return false;
}
public virtual void Delete()
public virtual void Delete(SharpTreeNode[] nodes)
{
throw new NotSupportedException(GetType().Name + " does not support deletion");
}
public virtual void DeleteCore()
public virtual void DeleteWithoutConfirmation(SharpTreeNode[] nodes)
{
throw new NotSupportedException(GetType().Name + " does not support deletion");
}
public virtual IDataObject Copy(SharpTreeNode[] nodes)
public virtual bool CanCut(SharpTreeNode[] nodes)
{
throw new NotSupportedException(GetType().Name + " does not support copy/paste or drag'n'drop");
return CanCopy(nodes) && CanDelete(nodes);
}
/*
public virtual bool CanCopy(SharpTreeNode[] nodes)
{
return false;
public virtual void Cut(SharpTreeNode[] nodes)
{
var data = GetDataObject(nodes);
if (data != null) {
// TODO: default cut implementation should not immediately perform deletion, but use 'IsCut'
Clipboard.SetDataObject(data, copy: true);
DeleteWithoutConfirmation(nodes);
}
}
public virtual bool CanPaste(IDataObject data)
{
return false;
}
public virtual bool CanCopy(SharpTreeNode[] nodes)
{
return false;
}
public virtual void Paste(IDataObject data)
{
EnsureLazyChildren();
Drop(data, Children.Count, DropEffect.Copy);
}
*/
#endregion
public virtual void Copy(SharpTreeNode[] nodes)
{
var data = GetDataObject(nodes);
if (data != null)
Clipboard.SetDataObject(data, copy: true);
}
#region Drag and Drop
public virtual bool CanDrag(SharpTreeNode[] nodes)
protected virtual IDataObject GetDataObject(SharpTreeNode[] nodes)
{
return null;
}
public virtual bool CanPaste(IDataObject data)
{
return false;
}
public virtual void Paste(IDataObject data)
{
throw new NotSupportedException(GetType().Name + " does not support copy/paste");
}
#endregion
#region Drag and Drop
public virtual void StartDrag(DependencyObject dragSource, SharpTreeNode[] nodes)
{
DragDropEffects effects = DragDropEffects.All;
if (!nodes.All(n => n.CanDelete()))
effects &= ~DragDropEffects.Move;
DragDropEffects result = DragDrop.DoDragDrop(dragSource, Copy(nodes), effects);
// The default drag implementation works by reusing the copy infrastructure.
// Derived classes should override this method
var data = GetDataObject(nodes);
if (data == null)
return;
DragDropEffects effects = DragDropEffects.Copy;
if (CanDelete(nodes))
effects |= DragDropEffects.Move;
DragDropEffects result = DragDrop.DoDragDrop(dragSource, data, effects);
if (result == DragDropEffects.Move) {
foreach (SharpTreeNode node in nodes)
node.DeleteCore();
DeleteWithoutConfirmation(nodes);
}
}
public virtual bool CanDrop(DragEventArgs e, int index)
/// <summary>
/// Gets the possible drop effects.
/// If the method returns more than one of (Copy|Move|Link), the tree view will choose one effect based
/// on the allowed effects and keyboard status.
/// </summary>
public virtual DragDropEffects GetDropEffect(DragEventArgs e, int index)
{
return false;
// Since the default drag implementation uses Copy(),
// we'll use Paste() in our default drop implementation.
if (CanPaste(e.Data)) {
// If Ctrl is pressed -> copy
// If moving is not allowed -> copy
// Otherwise: move
if ((e.KeyStates & DragDropKeyStates.ControlKey) != 0 || (e.AllowedEffects & DragDropEffects.Move) == 0)
return DragDropEffects.Copy;
return DragDropEffects.Move;
}
return DragDropEffects.None;
}
internal void InternalDrop(DragEventArgs e, int index)
@ -612,7 +648,9 @@ namespace ICSharpCode.TreeView @@ -612,7 +648,9 @@ namespace ICSharpCode.TreeView
public virtual void Drop(DragEventArgs e, int index)
{
throw new NotSupportedException(GetType().Name + " does not support Drop()");
// Since the default drag implementation uses Copy(),
// we'll use Paste() in our default drop implementation.
Paste(e.Data);
}
#endregion

7
src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeNodeView.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Controls;
@ -150,8 +151,10 @@ namespace ICSharpCode.TreeView @@ -150,8 +151,10 @@ namespace ICSharpCode.TreeView
else {
result -= 19;
}
if (result < 0)
throw new InvalidOperationException();
if (result < 0) {
Debug.WriteLine("Negative indent level detected for node " + Node);
result = 0;
}
return result;
}
}

68
src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs

@ -355,7 +355,7 @@ namespace ICSharpCode.TreeView @@ -355,7 +355,7 @@ namespace ICSharpCode.TreeView
if (Root != null && !ShowRoot) {
e.Handled = true;
Root.CanDrop(e, Root.Children.Count);
e.Effects = Root.GetDropEffect(e, Root.Children.Count);
}
}
@ -365,7 +365,9 @@ namespace ICSharpCode.TreeView @@ -365,7 +365,9 @@ namespace ICSharpCode.TreeView
if (Root != null && !ShowRoot) {
e.Handled = true;
Root.InternalDrop(e, Root.Children.Count);
e.Effects = Root.GetDropEffect(e, Root.Children.Count);
if (e.Effects != DragDropEffects.None)
Root.InternalDrop(e, Root.Children.Count);
}
}
@ -377,10 +379,12 @@ namespace ICSharpCode.TreeView @@ -377,10 +379,12 @@ namespace ICSharpCode.TreeView
internal void HandleDragOver(SharpTreeViewItem item, DragEventArgs e)
{
HidePreview();
e.Effects = DragDropEffects.None;
var target = GetDropTarget(item, e);
if (target != null) {
e.Handled = true;
e.Effects = target.Effect;
ShowPreview(target.Item, target.Place);
}
}
@ -393,6 +397,7 @@ namespace ICSharpCode.TreeView @@ -393,6 +397,7 @@ namespace ICSharpCode.TreeView
var target = GetDropTarget(item, e);
if (target != null) {
e.Handled = true;
e.Effects = target.Effect;
target.Node.InternalDrop(e, target.Index);
}
} catch (Exception ex) {
@ -414,6 +419,7 @@ namespace ICSharpCode.TreeView @@ -414,6 +419,7 @@ namespace ICSharpCode.TreeView
public double Y;
public SharpTreeNode Node;
public int Index;
public DragDropEffects Effect;
}
DropTarget GetDropTarget(SharpTreeViewItem item, DragEventArgs e)
@ -485,13 +491,14 @@ namespace ICSharpCode.TreeView @@ -485,13 +491,14 @@ namespace ICSharpCode.TreeView
GetNodeAndIndex(item, place, out node, out index);
if (node != null) {
e.Effects = DragDropEffects.None;
if (node.CanDrop(e, index)) {
var effect = node.GetDropEffect(e, index);
if (effect != DragDropEffects.None) {
DropTarget target = new DropTarget() {
Item = item,
Place = place,
Node = node,
Index = index
Index = index,
Effect = effect
};
targets.Add(target);
}
@ -614,45 +621,78 @@ namespace ICSharpCode.TreeView @@ -614,45 +621,78 @@ namespace ICSharpCode.TreeView
static void HandleExecuted_Cut(object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
SharpTreeView treeView = (SharpTreeView)sender;
var nodes = treeView.GetTopLevelSelection().ToArray();
if (nodes.Length > 0)
nodes[0].Cut(nodes);
}
static void HandleCanExecute_Cut(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
SharpTreeView treeView = (SharpTreeView)sender;
var nodes = treeView.GetTopLevelSelection().ToArray();
e.CanExecute = nodes.Length > 0 && nodes[0].CanCut(nodes);
e.Handled = true;
}
static void HandleExecuted_Copy(object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
SharpTreeView treeView = (SharpTreeView)sender;
var nodes = treeView.GetTopLevelSelection().ToArray();
if (nodes.Length > 0)
nodes[0].Copy(nodes);
}
static void HandleCanExecute_Copy(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
SharpTreeView treeView = (SharpTreeView)sender;
var nodes = treeView.GetTopLevelSelection().ToArray();
e.CanExecute = nodes.Length > 0 && nodes[0].CanCopy(nodes);
e.Handled = true;
}
static void HandleExecuted_Paste(object sender, ExecutedRoutedEventArgs e)
{
SharpTreeView treeView = (SharpTreeView)sender;
var data = Clipboard.GetDataObject();
if (data != null) {
var selectedNode = (treeView.SelectedItem as SharpTreeNode) ?? treeView.Root;
if (selectedNode != null)
selectedNode.Paste(data);
}
e.Handled = true;
}
static void HandleCanExecute_Paste(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
SharpTreeView treeView = (SharpTreeView)sender;
var data = Clipboard.GetDataObject();
if (data == null) {
e.CanExecute = false;
} else {
var selectedNode = (treeView.SelectedItem as SharpTreeNode) ?? treeView.Root;
e.CanExecute = selectedNode != null && selectedNode.CanPaste(data);
}
e.Handled = true;
}
static void HandleExecuted_Delete(object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
SharpTreeView treeView = (SharpTreeView)sender;
foreach (SharpTreeNode node in treeView.GetTopLevelSelection().ToArray())
node.Delete();
var nodes = treeView.GetTopLevelSelection().ToArray();
if (nodes.Length > 0)
nodes[0].Delete(nodes);
}
static void HandleCanExecute_Delete(object sender, CanExecuteRoutedEventArgs e)
{
SharpTreeView treeView = (SharpTreeView)sender;
e.CanExecute = treeView.GetTopLevelSelection().All(node => node.CanDelete());
var nodes = treeView.GetTopLevelSelection().ToArray();
e.CanExecute = nodes.Length > 0 && nodes[0].CanDelete(nodes);
e.Handled = true;
}
/// <summary>

4
src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeViewItem.cs

@ -78,9 +78,7 @@ namespace ICSharpCode.TreeView @@ -78,9 +78,7 @@ namespace ICSharpCode.TreeView
Math.Abs(currentPoint.Y - startPoint.Y) >= SystemParameters.MinimumVerticalDragDistance) {
var selection = ParentTreeView.GetTopLevelSelection().ToArray();
if (Node.CanDrag(selection)) {
Node.StartDrag(this, selection);
}
Node.StartDrag(this, selection);
}
}
}

Loading…
Cancel
Save