SP2: TreeView control

J

Jon Pawley

Hi,

I have this problem with the .NETCF TreeView control, and I'm pretty
sure someone else had the same or a similar problem a wee while back.

Basically, I need to work out a way of detecting when the user taps
on a node in a TreeView control.

The .NET Compact Framework Frequently Asked Questions (at
http://msdn.microsoft.com/mobility/prodtechinfo/devtools/netcf/FAQ/default.aspx)
has this to say:
5.36. How do I get notified when the user
clicks on a treeview node?

TreeView does not support the Click event;
however, you can workaround this by using
the AfterSelect event instead.

Well, that sounds reasonable, and I've given it a pretty good satb,
using the AfterSelect event. It's not perfect, but I can almost do
what I need. However there are two deficiencies that have me stumped,
and wondered whether anyone had a solution?


Problem 1: AfterSelect does not get fired if the user taps on a node
that is already selected.

Scenario: A form has a TreeView with a bunch of entries. Tapping on
one of the entries opens up a new form which allows the user to edit
the data associated with that node.

Thing is, the first node that is displayed automatically gets selected
before I can do anything about it. So, if the user wants to edit the
data associated with the first node that is displayed they have to tap
on any other node, which casues the secondary form to be displayed)
close that form, and then tap on the first node, the one they really
wanted. Hmm... and we are to explain that to our users how, exactly?



Well, then I thought, "OK, why don't I just set the
TreeView.SelectedNode to null, then nothing will be selected and then
the user will be able to tap on the first displayed node and
everything will be OK." Nope. Setting TreeView.SelectedNode to null
seems to have no effect. The initial form still shows the first
displayed node as being selected, so that doesn't work. (And besides,
it's not really a completed solution to not getting an evet when the
user taps on an already selected node.)


I was wondering whether there is a way to "subvert" .NETCF on this
one, and do some kind of magic P/Invoke thing to set the selected node
in the tree to "nothing". I haven't yet got to grips with P/Invoke
(probably about time, though...) and wondered if anyone had any
pointers? Thanks.



Problem 2: can't distinguish between a user selecting a node because
they tapped on it (and hence, want to edit the data associated with
the node) and the user tapping-and-holding because they want to pop-up
a context menu associated with the TreeView control.

Scenario: Pretty self explanatory. User might tap-and-hold (to get the
"red dots" or "Ring Of Fire") to pop-up the context menu, or they
might simply tap in order to open up the data editing form.
Unfortunatley MS didn't provide a
TreeView.PredictWhatTheUserWantsToDo() method... ;)


Well, I've been working on this for a while, and the only half decent
thing I can do is, in the AfterSelect handler, do a
System.Threading.Thread.Sleep(200); and then test the state of the
Control.MouseButtons to see if the stylus is still in contact with the
touch screen. It is only half decent, isn't it? For how long should I
Sleep()? My latest idea is to play around with the
SystemInformation.DoubleClickTime to see if that is a suitable value
to use... I'll have to see.



My conclusion is that the TreeView control as provided by .NETCF SP2
is only barely adequate. I don't suppose there is any chance of
getting some MouseEvents from the control? (I can't understand why,
when TreeView is derived from Control, which does emit these--and a
few more--events, MS decided to keep them from us. There must be
something I don't fully understand...)


And, how do I explain to my employer that the TreeView control is
inadequate? "Ah, but you could do that easily in VB, *surely* you can
do it in .NET...," he says.


Seems I'm going to have to roll up my sleeves an implement a custom
tree view control that *is* adequate. Unless anyone has other ideas on
how to get around these problems? (And, I guess, it would be kind of
nice to hear from MS and explain why their TreeView is deficient.)


Cheers,

Jo
 
J

Jon Pawley

Dear Kenan,

Thank you for reading my rather long posting, and giving a pretty good
suggestion. Adding an "edit" option to the context menu is a fairly
good workaround, and I think I'll add that in, but it is just a
workaround.

Imagine if, on your desktop, when using Windows Explorer, rather than
clicking on one of your folders, you had to right-click then pick
"Expand" from the context menu... you'd start to get a little cheesed
off with the poorly implemented UI. I believe the same holds for my
..NETCF app. Making the user tap-and-hold then select an item from the
context menu is simply more complex than allowing them to just tap on
the item, and will lead to impression of a poor UI.

Still, given that MS haven't provided a decent way to get finer
control over their .NETCF TreeView control, I'm going to give this
kludgy workaround a go. I don't see any other option...

Thanks Kenan,

Jon
 
K

Katie Schaeffer [MSFT]

Hi Jo,

Sorry it took so long for you to get a response. So, first, I wanted to
pass onto you that we are considering adding mouse events for more
controls. The main reason these arn't already added is for performance
considerations. Passing events from native -> managed code is not
completly free, and when you consider the amount of events passed when the
user takes the stylus and drags it across the screen, you're talking about
a decent amount of message sending. That said, we are listening to you and
we are taking it into consideration. It especially helps to hear about
scenarios that are difficult or impossible because of the absence of events
- so let me know if you think of any other scenarios. Also, we do have
some additional treeview-specific events on the table for our next version.

As for your scenario - it looks like even the desktop framework has the
notion that 1 treenode is always selected (they start out with the first
node selected). You can use the ContextMenu.Popup event to determine when
a tap&hold has occured (but this would be fired after the mouse or
afterselect event anyway). So I think I like Kenan's suggestion of adding
an 'Edit' option to the context menu.

Anyhow, I shall pass on your scenario - let me know if you have any other
pain-points.

-Katie

This posting is provided "AS IS" with no warranties, and confers no rights.

***.Net Compact Framework Info***
Faq:
http://msdn.microsoft.com/mobility/prodtechinfo/devtools/netcf/FAQ/default.a
spx
QuickStarts: http://samples.gotdotnet.com/quickstart/CompactFramework/
Samples:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/h
tml/CompactfxTechArt.asp

--------------------
| From: (e-mail address removed) (Jon Pawley)
| Newsgroups: microsoft.public.dotnet.framework.compactframework
| Subject: SP2: TreeView control
| Date: 22 Dec 2003 13:44:46 -0800
| Organization: http://groups.google.com
| Lines: 108
| Message-ID: <[email protected]>
| NNTP-Posting-Host: 203.97.48.193
| Content-Type: text/plain; charset=ISO-8859-1
| Content-Transfer-Encoding: 8bit
| X-Trace: posting.google.com 1072129486 6249 127.0.0.1 (22 Dec 2003
21:44:46 GMT)
| X-Complaints-To: (e-mail address removed)
| NNTP-Posting-Date: Mon, 22 Dec 2003 21:44:46 +0000 (UTC)
| Path:
cpmsftngxa07.phx.gbl!cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.su
l.t-online.de!t-online.de!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!po
stnews1.google.com!not-for-mail
| Xref: cpmsftngxa07.phx.gbl
microsoft.public.dotnet.framework.compactframework:41580
| X-Tomcat-NG: microsoft.public.dotnet.framework.compactframework
|
| Hi,
|
| I have this problem with the .NETCF TreeView control, and I'm pretty
| sure someone else had the same or a similar problem a wee while back.
|
| Basically, I need to work out a way of detecting when the user taps
| on a node in a TreeView control.
|
| The .NET Compact Framework Frequently Asked Questions (at
|
http://msdn.microsoft.com/mobility/prodtechinfo/devtools/netcf/FAQ/default.a
spx)
| has this to say:
|
| >
| >
| > 5.36. How do I get notified when the user
| > clicks on a treeview node?
| >
| > TreeView does not support the Click event;
| > however, you can workaround this by using
| > the AfterSelect event instead.
| >
| >
|
| Well, that sounds reasonable, and I've given it a pretty good satb,
| using the AfterSelect event. It's not perfect, but I can almost do
| what I need. However there are two deficiencies that have me stumped,
| and wondered whether anyone had a solution?
|
|
| Problem 1: AfterSelect does not get fired if the user taps on a node
| that is already selected.
|
| Scenario: A form has a TreeView with a bunch of entries. Tapping on
| one of the entries opens up a new form which allows the user to edit
| the data associated with that node.
|
| Thing is, the first node that is displayed automatically gets selected
| before I can do anything about it. So, if the user wants to edit the
| data associated with the first node that is displayed they have to tap
| on any other node, which casues the secondary form to be displayed)
| close that form, and then tap on the first node, the one they really
| wanted. Hmm... and we are to explain that to our users how, exactly?
|
|
|
| Well, then I thought, "OK, why don't I just set the
| TreeView.SelectedNode to null, then nothing will be selected and then
| the user will be able to tap on the first displayed node and
| everything will be OK." Nope. Setting TreeView.SelectedNode to null
| seems to have no effect. The initial form still shows the first
| displayed node as being selected, so that doesn't work. (And besides,
| it's not really a completed solution to not getting an evet when the
| user taps on an already selected node.)
|
|
| I was wondering whether there is a way to "subvert" .NETCF on this
| one, and do some kind of magic P/Invoke thing to set the selected node
| in the tree to "nothing". I haven't yet got to grips with P/Invoke
| (probably about time, though...) and wondered if anyone had any
| pointers? Thanks.
|
|
|
| Problem 2: can't distinguish between a user selecting a node because
| they tapped on it (and hence, want to edit the data associated with
| the node) and the user tapping-and-holding because they want to pop-up
| a context menu associated with the TreeView control.
|
| Scenario: Pretty self explanatory. User might tap-and-hold (to get the
| "red dots" or "Ring Of Fire") to pop-up the context menu, or they
| might simply tap in order to open up the data editing form.
| Unfortunatley MS didn't provide a
| TreeView.PredictWhatTheUserWantsToDo() method... ;)
|
|
| Well, I've been working on this for a while, and the only half decent
| thing I can do is, in the AfterSelect handler, do a
| System.Threading.Thread.Sleep(200); and then test the state of the
| Control.MouseButtons to see if the stylus is still in contact with the
| touch screen. It is only half decent, isn't it? For how long should I
| Sleep()? My latest idea is to play around with the
| SystemInformation.DoubleClickTime to see if that is a suitable value
| to use... I'll have to see.
|
|
|
| My conclusion is that the TreeView control as provided by .NETCF SP2
| is only barely adequate. I don't suppose there is any chance of
| getting some MouseEvents from the control? (I can't understand why,
| when TreeView is derived from Control, which does emit these--and a
| few more--events, MS decided to keep them from us. There must be
| something I don't fully understand...)
|
|
| And, how do I explain to my employer that the TreeView control is
| inadequate? "Ah, but you could do that easily in VB, *surely* you can
| do it in .NET...," he says.
|
|
| Seems I'm going to have to roll up my sleeves an implement a custom
| tree view control that *is* adequate. Unless anyone has other ideas on
| how to get around these problems? (And, I guess, it would be kind of
| nice to hear from MS and explain why their TreeView is deficient.)
|
|
| Cheers,
|
| Jo
|
 
M

Mark Johnson

// - so let me know if you think of any other scenarios
TreeView.LabelEdit = true; to Edit Label for the AfterLabelEdit Event
- to Change the Text in the Tree Node
and BeforeLabelEdit to prevent certin Nodes being changed in the first
place.

would be important improvemnet of the TreeView Funtionality.

BeforeCollapse would be nice to change the Images as on the PC
if (e.Action.ToString() == "Collapse")
{ // will not work in BeforeExpand and not supported on
Framework.Compact
if (e.Node.ImageIndex == 2)
e.Node.ImageIndex = 1;
if (e.Node.ImageIndex == 6)
e.Node.ImageIndex = 5;

I could do without BeforeCollapse (more cosmetic than usefull),
but AfterLabelEdit (and to be User friendly : BeforeLabelEdit ) would be
usefull.

Mark Johnson, Berlin Germany
(e-mail address removed)
 
J

Jon Pawley

Dear Katie,

Many thanks for your message. Don't worry about the delay... Hey--it was
Christmas! ;)

It's really good to know that Microsoft are open to taking suggestions for
improvements from developers out in the field, and it's perhaps even better
to know that additional "mouse" events are on the cards.

It's good to be reminded that getting events from native code into managed
code isn't free, so thanks for that. It certainly helps to explain why there
aren't currently as many bits and pieces as everyone wants... I guess it is
a case of not being able to please everybody all the time, and trying to get
the balance between resource constraints and full feature sets must be
difficult.

To be honest, I don't think that heaps more "mouse" events would be needed,
but then that is only my opinion. I think that getting a MouseDown event and
maybe a MouseUp event in most controls would be sufficient. If I then wanted
to work out whether a MouseDown event corresponded to someone, say, tapping
on a TreeViewItem to give it focus, as opposed to tapping on an already
focussed TreeViewItem, well, that would be down to me. I don't think I would
need any other events (such as "BeforeGotFocus" or "AfterLostFocus"), but
then maybe that is just because of the way *I* am wanting to use this
control.

I would question the usefulness of getting "MouseMove" events (or the
equivalant for non-moused environments!) in .NETCF. There is very little
dragging that happens, in my limited experience, on PPCs. The exception
might be in a control that captured handwriting. There doesn't seem to be
much concept of dragging icons around the screen...

Here's an idea--is there any possibility of having one set of controls that
have minimal events, and another set of controls that have a richer set of
events? That way the developer would be able to make the choice between a
performance hit and a feature set thet may be desirable. Hmm...?

Anyway, thanks again for your response. And I wont push you for any dates
relating to .NETCF v2 ;)

Cheers,

Jon
 
M

Mark Johnson

MouseDown/Up/Move events are suppoted on Panels at least.
I use these for a Card Game Logic Class to support the Drag and Drop as used
in Solitair.
So I hope this will remain as is.

// and trying to get the balance between resource constraints and full
feature sets must be difficult.
Yes, I think Microsoft is very wise to be carefull here. I think they
remember what happen with OS2 that
(not to mention the unfriendly User-Interface) was simply doing to much on a
386/486 Maschine.
The concept (if I remember correctly) was simaler to .NET Framework -
everything were Objects.
No doubt they thanked the stars that they pulled out of the OS2 project when
they did, avoiding the mess that IBM got into.

As the Maschines grow stronger more Events can be built in when needed.
With this in mind they seem to be doing a good job of balancing the pros and
cons.

No doubt they tried a full fledged Framework on Compact with sluggisch
results á la OS2.
Lesson well learned.

Mark Johnson, Berlin Germany
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top