目标:让我们建立一个树形结构菜单,具体的说用一个TreeView来显示菜单。先看效果图
1、首先我们需要建立一个自定义的TreeView,实现单击事件。
namespace CustomUIElements
...{
public delegate void NodeClickedEvent(object sender, TreeNode nodeClicked);
public class ClickableTreeNode : TreeNode
...{
ClickableTreeView _parent = null;
public event EventHandler NodeClick;
private bool _needsSetup = false;
public bool NeedsSetup
...{
get ...{ return _needsSetup; }
}
public ClickableTreeNode()
: base()
...{
_needsSetup = true;
}
public new ClickableTreeView TreeView
...{
get ...{ return _parent; }
}
public void SetUp(ClickableTreeView tv)
...{
ClickableTreeView clickable = tv as ClickableTreeView;
if (clickable == null) throw new Exception("The clickable tree node was added to a non-clickable tree view");
_parent = clickable;
// register for the node clicked event, when *a* node gets clicked
clickable.NodeClicked += new NodeClickedEvent(clickable_NodeClicked);
_needsSetup = false;
}
public ClickableTreeNode(ClickableTreeView tv) : base()
...{
ClickableTreeView clickable = tv as ClickableTreeView;
if (clickable == null) throw new Exception("The clickable tree node was added to a non-clickable tree view");
_parent = clickable;
// register for the node clicked event, when *a* node gets clicked
clickable.NodeClicked += new NodeClickedEvent(clickable_NodeClicked);
}
void clickable_NodeClicked(object sender, TreeNode nodeClicked)
...{
// if the node is actually us, then fire the NodeClick event...
if ((nodeClicked as ClickableTreeNode) == this)
...{
if (NodeClick != null)
NodeClick(this, new EventArgs());
}
}
}
public class ClickableTreeView : TreeView
...{
public event NodeClickedEvent NodeClicked;
public ClickableTreeView() : base()
...{
this.MouseClick += new MouseEventHandler(ClickableTreeView_MouseClick);
}
void ClickableTreeView_MouseClick(object sender, MouseEventArgs e)
...{
TreeViewHitTestInfo inf = HitTest(e.X, e.Y);
if (inf.Node == null) return; // didnt click a node...
// we clicked a node, so notify that one was clicked...
if (NodeClicked != null)
NodeClicked(this, inf.Node);
}
}
}
...{
public delegate void NodeClickedEvent(object sender, TreeNode nodeClicked);
public class ClickableTreeNode : TreeNode
...{
ClickableTreeView _parent = null;
public event EventHandler NodeClick;
private bool _needsSetup = false;
public bool NeedsSetup
...{
get ...{ return _needsSetup; }
}
public ClickableTreeNode()
: base()
...{
_needsSetup = true;
}
public new ClickableTreeView TreeView
...{
get ...{ return _parent; }
}
public void SetUp(ClickableTreeView tv)
...{
ClickableTreeView clickable = tv as ClickableTreeView;
if (clickable == null) throw new Exception("The clickable tree node was added to a non-clickable tree view");
_parent = clickable;
// register for the node clicked event, when *a* node gets clicked
clickable.NodeClicked += new NodeClickedEvent(clickable_NodeClicked);
_needsSetup = false;
}
public ClickableTreeNode(ClickableTreeView tv) : base()
...{
ClickableTreeView clickable = tv as ClickableTreeView;
if (clickable == null) throw new Exception("The clickable tree node was added to a non-clickable tree view");
_parent = clickable;
// register for the node clicked event, when *a* node gets clicked
clickable.NodeClicked += new NodeClickedEvent(clickable_NodeClicked);
}
void clickable_NodeClicked(object sender, TreeNode nodeClicked)
...{
// if the node is actually us, then fire the NodeClick event...
if ((nodeClicked as ClickableTreeNode) == this)
...{
if (NodeClick != null)
NodeClick(this, new EventArgs());
}
}
}
public class ClickableTreeView : TreeView
...{
public event NodeClickedEvent NodeClicked;
public ClickableTreeView() : base()
...{
this.MouseClick += new MouseEventHandler(ClickableTreeView_MouseClick);
}
void ClickableTreeView_MouseClick(object sender, MouseEventArgs e)
...{
TreeViewHitTestInfo inf = HitTest(e.X, e.Y);
if (inf.Node == null) return; // didnt click a node...
// we clicked a node, so notify that one was clicked...
if (NodeClicked != null)
NodeClicked(this, inf.Node);
}
}
}
2、我们需要的是建立两个我们自己的类,分别实现IUIElementAdapterFactory和UIElementAdapter<T>。
public class ClickableTreeViewAdapterFactory : IUIElementAdapterFactory
...{
IUIElementManagerFactory Members#region IUIElementManagerFactory Members
public IUIElementAdapter GetAdapter(object managedExtension)
...{
if (managedExtension is ClickableTreeNode)
return new ClickableTreeViewAdapter(managedExtension as ClickableTreeNode);
else if (managedExtension is ClickableTreeView)
return new ClickableTreeViewAdapter(managedExtension as ClickableTreeView);
return null;
}
#endregion
IUIElementAdapterFactory Members#region IUIElementAdapterFactory Members
public bool Supports(object uiElement)
...{
if (uiElement is ClickableTreeNode)
return true;
else if (uiElement is ClickableTreeView)
return true;
else
return false;
}
#endregion
}
...{
IUIElementManagerFactory Members#region IUIElementManagerFactory Members
public IUIElementAdapter GetAdapter(object managedExtension)
...{
if (managedExtension is ClickableTreeNode)
return new ClickableTreeViewAdapter(managedExtension as ClickableTreeNode);
else if (managedExtension is ClickableTreeView)
return new ClickableTreeViewAdapter(managedExtension as ClickableTreeView);
return null;
}
#endregion
IUIElementAdapterFactory Members#region IUIElementAdapterFactory Members
public bool Supports(object uiElement)
...{
if (uiElement is ClickableTreeNode)
return true;
else if (uiElement is ClickableTreeView)
return true;
else
return false;
}
#endregion
}
public class ClickableTreeViewAdapter: UIElementAdapter<ClickableTreeNode>
...{
private ClickableTreeView _managed = null;
private ClickableTreeNode _managedNode = null;
public ClickableTreeViewAdapter(ClickableTreeView element)
...{
_managed = element;
}
public ClickableTreeViewAdapter(ClickableTreeNode node)
...{
_managedNode = node;
}
protected override void Remove(ClickableTreeNode uiElement)
...{
if (_managed != null)
...{
if (!_managed.IsDisposed)
...{
if (_managed.Nodes.Contains(uiElement))
_managed.Nodes.Remove(uiElement);
}
}
else if (_managedNode != null)
...{
if (!_managedNode.TreeView.IsDisposed)
...{
if (_managedNode.Nodes.Contains(uiElement))
_managedNode.Nodes.Remove(uiElement);
}
}
}
protected override ClickableTreeNode Add(ClickableTreeNode item)
...{
if (_managed != null)
...{
private ClickableTreeView _managed = null;
private ClickableTreeNode _managedNode = null;
public ClickableTreeViewAdapter(ClickableTreeView element)
...{
_managed = element;
}
public ClickableTreeViewAdapter(ClickableTreeNode node)
...{
_managedNode = node;
}
protected override void Remove(ClickableTreeNode uiElement)
...{
if (_managed != null)
...{
if (!_managed.IsDisposed)
...{
if (_managed.Nodes.Contains(uiElement))
_managed.Nodes.Remove(uiElement);
}
}
else if (_managedNode != null)
...{
if (!_managedNode.TreeView.IsDisposed)
...{
if (_managedNode.Nodes.Contains(uiElement))
_managedNode.Nodes.Remove(uiElement);
}
}
}
protected override ClickableTreeNode Add(ClickableTreeNode item)
...{
if (_managed != null)