|
So when a node is selected/deselected the ForeColor property is changed. In my little partial implementation of your control, I'm setting the highlights to SystemColors.HighlightText and the BackColor is set to SystemColors.Highlight so that it retains the users system settings for highlights and what not. The problem occurrs when the control is disabled. Because the ForeColor/BackColor colors have been set, it no longer draws the nodes in the disabled state, but retains the ForeColor/BackColor that was set when the node was highlighted/unhighlighted. This can cause some very strage color combinations as nodes are programatically selected/deselected while the control is both enabled and disabled. If you've got an easy fix for this, please let me know.
Jebrew
|
|
|
|
|
I'm interested in your latest version. You mentioned that you were going to work on DataBinding next. Please give me information on the control and let me know what the price is.
Thanks,
Jacob
|
|
|
|
|
Hi,
before everything I would like to say, great job and thank you givin' us this great TreeView "update".
So well... ok. How to explain it.
As an example, when you have to remove node(s) and you forget to call the ClearSelNodes() method you've got really bad news. In fact, 'cause in .Net you cannot have dangling pointers, after calling the Clear() method of the TreeNodeCollection, the ArrayList (or hashing table in our case) that contain the selected nodes will contain nodes that now... got no treeview associated. This will givin' you "null reference" exception at Deselect() method in MWTreeNodeWrapper class, the next time you try to select a node.
<br />
public static void Deselect(MWTreeNodeWrapper mwtnw)<br />
{<br />
...<br />
<br />
if(mwtnw.Node.TreeView.Enabled)<br />
<br />
...<br />
The way I think we can fixe this "logical bug", is by overriding the Clear() method of the TreeNodeCollection and adding the ClearSelNodes() method call. The problem is, we cannot implemente a "new" TreeNodeCollection, I tried before and failed for some out of reach reasons caused by the Microsoft product itself.
The other way we can fixe it, is to manually check for "orphan" nodes (nodes without a TreeView) at strategicals locations in the MWTreeView control itself. "Patching" the TreeView is not a great way solving the problem and I don't wanna do this for the simple reason that if you release a new version of the TreeView, I'll be stuck to done the job each time.
Sorry for my bad english, I hope my explanations was pretty easy to understand.
So... what's your opinion about this "bug" ?
|
|
|
|
|
Thanks for the nice words.
I think I have written more code to 'help' the MS TreeView than the whole MS TreeView required...
Note that there is no bug when selecting TreeNodes when programming for it properly in current versions. Read on and I will explain why.
The code has changed quite a bit for the latest versions. This is what the static Deselect method looks like now:
public static void Deselect(MWTreeNodeWrapper mwtnw)<br />
{<br />
mwtnw.Node.ImageIndex = mwtnw.ImageIndex;<br />
mwtnw.Node.SelectedImageIndex = mwtnw.SelectedImageIndex;<br />
<br />
if( mwtnw != null &&<br />
mwtnw.Node != null &&<br />
(mwtnw.Node.TreeView == null ||<br />
mwtnw.Node.TreeView.Enabled))<br />
{<br />
mwtnw.Node.BackColor = mwtnw.BackColor;<br />
mwtnw.Node.ForeColor = mwtnw.ForeColor;<br />
}<br />
}
So no exceptions should be thrown.
It is really up to the programmer using the MWTreeView to remove TreeNodes from the SelNodes collection if they are removed from the MWTreeView.
I.e. if a ContextMenu has a 'Delete Node' item then the code behind this item should both remove the TreeNode from the SelNodes collection and from its parent (whether that is a TreeNode or the TreeView itself).
It is really a shame that you cannot instantiate TreeNodeCollections etc. Hope this changes sometime in the future.
What you write about checking for orphan TreeNodes (orphan, parent, child - what is this, some family reunion or something? ) would not be necessary if the code where TreeNodes are removed, cleared or whatever also deals with the SelNodes collection.
If we could override the TreeNodeCollections class etc the whole job of the MWTreeView would have been so much easier.
But part of the challenge is to be able to do it to the current MS TreeView
Considering all your TreeView-related questions, are you creating your own TreeView, inheriting from the MS TreeView or using the MWTreeView (curious)?
|
|
|
|
|
With all respect I've got for you and your job, I inheriting from your treeview of course !
Blindly modify your control directly in your code isn't a great programming practice and I consider peoples doin' this as robbers stealing you.
Here I'm working on an kind of personnal "Help Documentation Editor" 100% object oriented with section, sub section, each of these are makin' of "Elements" (text element, tips element, link element, table element, picture element, list element). Using WinForm with MDI Forms, I think you can see how important the treeview is. It must handle Drag&Drop, easy multiple selection and some "internals law" that telling orders like "you cannot drop a section (node) before the root section of the document (~the ultimate parent of all nodes in the treeview)".
So yeah, I'm workin' hard on the TreeView Control... and it's really pain fully !!!
I agree with you about that there's no bug, at it's real meaning, between the SelNodes and the Nodes
collections. But I think we also agree that we must "synchronize" these 2 collections and the best way doing it, is by implementing our version of the TreeNodeCollection. Seems that's impossible, I agree with you about the shame limitations of the -MS- TreeNodeCollections...
Thanks for the "uptodate version" of the Deselect() method. Are you planning to release a third version of you TreeView (soon or not) ? (I'm also curious )
|
|
|
|
|
Yep these two collections have to be synched - a shame this has to be done.
The further versions of the MWTreeView have gone commercial.
I am up to v2.1.1.4 as of yesterday actually. This version has full support for awesome very visual drag & drop (supporting multiple TreeNodes of course). There are also so many changes I just cannot list them all here.
I am also working on v3.x of the MWTreeView which has support for proper DataBinding, XML document reading etc. This is done to the extent that if a DataSource that is bound to the MWTreeView is resorted the MWTreeView immediately reflects this. DataBinding is also very customizable.
The version posted here on CodeProject is the last non-commercial version - it is still my work and nobody else should claim it as theirs yada yada yada...
|
|
|
|
|
where and how much will cost to buy it ?
|
|
|
|
|
Contact me on my mik adress. It can be found on netatonce.net.
Cannot write it in plain-text since I will get too much spam - and I don't eat spam
|
|
|
|
|
I'm using VS .NET 7.0
How to create a project...?
_____________________________
...and justice for all
APe
|
|
|
|
|
I will assume that you are using .NET Framework v1.1 (that is possible with VS 2002 isn't it?).
Unfortunately this requires some manual file copying etc:
You just create a new solution in VS called MWTreeViewTestApp and add a new Windows Control Library project which you call MWTreeView.
When this has been created you can remove the .cs file that is created by default (not AssemblyInfo.cs). Then copy all the .cs and .txt files from my solution directory into your new one using Windows Explorer. Do not copy any .resx, .csproj, .suo or other files.
Click on the project in the Solution Explorer of VS and a little icon will appear just below the name 'Solution Explorer - MWTreeView'. This icon is called 'Show All Files'. Now you will see all the files you manually copied from my solution directory tou yours. Right click on these files and select 'Include In Project'. When this has been done for all the files, you should be able to compile the project/solution.
The same procedure can be performed for the MWTreeViewTestApp project which is a Windows Application project added to the same solution. This will also have to have the Images directory copied intact.
In the MWTreeViewTestApp there is also one ImageList (ilMWTreeView) that you need to add Images to. The images should be 001.jpg and 002.jpg from the Images directory.
If you right-click on the projects and click Properties you can also enter 'MWControlSuite' as the Default Namespace.
Now you should have an MWTreeView and MWTreeViewTestApp that are the same as the ones for VS 2003.
Maybe there is even some converter application that has been written. I don't really know.
If you are using .NET Framework v1.0 I really suggest you upgrade since there is a bug in the MS TreeView that, if I remember correctly, raises the OnMouseUp event straight after the OnMouseDown event. I had a workaround for this in an older version of the MWTreeView, but I don't think I could achieve all the functionality in the MWTreeView v2 using .NET Framework v1.0.
|
|
|
|
|
It seems that the node ForeColor is lost with MWTreeView. Just set the ForeColor property to some node:
node.ForeColor = Color.LightGray
As soon as you click the node to select it and then you unselect it, the original ForeColor isn't restored.
I don't know if I can still use the ForeColor property on a TreeNode or if I need to use another property of the node wrapper implemented in MWCommon.
Marco Tenuti - www.tencas.com
|
|
|
|
|
It should work.
Have a look at the screenshot TreeNodeColors (the bottom one). Here I am using many different ForeColors (and BackColors).
The only problem you might be encountering is that you can't set ForeColor (or BackColor, ImageIndex and SelectedImageIndex) on a TreeNode when that TreeNode is selected. ForeColor and the other Properties that exist in the MWTreeNodeWrapper class must be set on the MWTreeNodeWrapper object for that particular TreeNode in the SelNodes Hashtable.
|
|
|
|
|
Your treeview control is very powerful and wonderful!Thank you!
Would you please give me an example code about a project codes that one treeview can drop into another treeview(those can be multi-selected).Thank you very much !
My email is :ycjin@citiz.net
David King
|
|
|
|
|
Do you mean one application with two MWTreeViews in it? If so, then I am working on code that does this. It is essentially finished, and has been for months now, but I haven't had much spare time lately to finish it up. It is code that is very visual; you can see exactly where you are moving or copying TreeNode(s) whether it be into other TreeNode(s) or in-between other TreeNodes.
You will just have to wait for this code to be finalized
At the moment I don't have any drag & drop code that works between two MWTreeViews in different applications since the TreeNodes are not serializable. I believe that the best way to do this is to write some form of serializer yourself, XML e.g.
|
|
|
|
|
Thank you for your answering my question.
If you finish this project code.Would you email me?Thank you!
I just want two treeviews in one application.Just multi-select is copied&moved by mouse drag&drop action.
I think you must spend your playing time in it.So Thank you very much!I am from China,and my English is poor
David King
|
|
|
|
|
No need of serialization at all. Just keep in mind that you have 2 differents instances of the TreeView. So in my case, I modify the DoDragDrop() function in OnItemDrag() by passing my item (the node).
this.DoDragDrop(e.Item, DragDropEffects.Move);
And at the OnDragDrop() fonction, you can reach the instance from where the node come.
<br />
TreeNode MovingNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");<br />
TreeView FROM = (TreeView)MovingNode.TreeView;<br />
At this point, you have just to modify your code by keeping in mind that now you have two instances of the TreeView ("this" and "FROM"). In that case, you will probably delete old nodes situated at the FROM TreeView .
That's it. The difficult part is getting data by passing the right string...
|
|
|
|
|
... of course it's just a little example to give you the idea... you'll probably passing an ArrayList, not only one node
Keep in mind that is futil to look at old selected nodes to know wich nodes you are about droping.
|
|
|
|
|
The way I have done drag & drop is by having a collection of TreeNodes that are passed (or actually MWTreeNodeWrappers).
By passing this in the drag & drop EventHandlers I get more than just the Text of the TreeNode(s); I can see if they are selected, should be expanded, BackColor, ForeColor, Font and all the other Properties that TreeNodes have.
When I do a drag & drop operation between two different applications and I debug in the one that the TreeNodes are dropped into (inside the OnDragDrop EventHandler) I can get my MWTreeNodeWrapper (mwtnw) out of the collection I am using. But when I put mwtnw into a Watch in Visual Studio, expand it and check the Node Property (where the TreeNode is) this is what I see:
System.Runtime.Remoting.Proxies.__TransparentProxy
And mwtnw.Node.Text contains this:
error: an exception of type: {System.Runtime.Remoting.RemotingException} occurred
I then get an exception with the following Message (when I try to access mwtnw.Node e.g.):
This remoting proxy has no channel sink which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server.
If I understand this correctly it means that I cannot do it because the TreeNode cannot be serialized which is what is required by a drag & drop operation between two separate applications.
Please tell me if I am doing something wrong here or if I have not understood how it should properly be done.
Have you tried doing this yourself? If so I would be very happy if you could send me some very simple (or not so simple, it doesn't really matter) test app that does this, and then I will investigate
|
|
|
|
|
oh ! I though that we was talking about "one application with two MWTreeViews" but... as we talk about D&D between two applications, these articles could be really usefull :
Drag and Drop files from Windows Explorer to Windows Form
Tool for viewing Drag and Drop and Clipboard formats
To be honest with you, I never tried to implement this kind of D&D...
But about "serializing" the TreeNodes, based on my knowledge, I guest that it would be very simple with binary serialisation on a "personal" inherited version of the Windoze.Forms.TreeNode.
But the problem is, where properly store the generated file after the serialization ? Put in C:\Temp isn't a really clean way... if you don't borded yourself with this detail, I don't mind how you could failed implementing the D&D between 2 applications.
What's you opinion about this "action plan" ?
|
|
|
|
|
One app with two MWTreeViews is no problem.
If you inherit from TreeNode you still cannot have automatic serialization but have to do it yourself. I just haven't bothered with this (yet?). This could be XML serialization e.g. like I mention a few comments up.
When serializing I wouldn't put it into a file at all - just putting it in memory is much better. That way you can achieve proper seamless drag & drop between two applications each with an MWTreeView.
|
|
|
|
|
Yeah, ok.
But how can you "share" an XML object created by serialization directly in memory, without passing by a "physical" file between 2 applications ? Is this a deep .Net trick... 'cause 2 differents applications mean 2 differents and independants memory heap, these heap and their integrity are "supposed" to be managed by the OS... but are you saying that .Net FrameWork offer a kind of bypass about this ?
If so, are you talking of SOAP ?
|
|
|
|
|
I haven't done it, but it should be possible to pass the XML as a string using the regular drag & drop operations.
As far as I understand you don't have to go any further than that. It should be pretty easy to create a test app that does this.
|
|
|
|
|
Sure, great idea... but if passing directly an Array of TreeNode failed like you said, that will probably be the same thing with a string that contain a "scrypted XML version" of the nodes.
|
|
|
|
|
A string can be passed I am sure. And what the string contains should be irrelevant.
Unfortunately parsing has to be done, which could slow the whole operation down quite a bit.
Maybe there is some way of checking if the MWTreeViews are in separate applications and only then do you use XML, otherwise a collection of TreeNodes. I am not sure this is possible though.
|
|
|
|
|
I think you are going too far... maybe asking some C# and/or .Net Guru, or directly a Microsoft Certified programmer, will help you much than imaginate a kind of big solution curving the real problem itself... I don't saying that you are wrong, but my opinion and my experience say "wow, there's probably something somewhere we passed through and we missed up an important detail"
... or maybe you're right, and you have found another great hole in the .Net Framework and his "famous" extremely poor TreeView control (I spent too much time on it, and it's really frustrating).
|
|
|
|