|
I'm not sure, but the fact you can interact with an unparented control might too be anomalous behavior, because I believe it is the form designer's responsibility to provide your ability to interact.
|
|
|
|
|
Well, then again, the anomalous behavior may be the result of being added to two separate Controls arrays -- somehow leaving you in a limbo where the Form designer *is* supporting interaction, but failed/aborted/reverted membership to the form's code body.
|
|
|
|
|
Sorry for the delay in responding...somewhere in one of your last posts opened the door and I have been able to get everything working. Part of the problem I was running in to seems to be a Visual Studio bug that required me to close VS and restart it to make sure that the designer was picking up the latest build of the control.
I'm putting the finishing touches on it tomorrow and then should, hopefully, get the green light to write this (or a slimmed down version at least) up as an article.
Thanks for the help you provided.
Thanks,
Scott.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Way to go, Scott.
I've had some other problems with VS as well -- all related to component development situations. I'm not sure I'm dealing with them the best way (you probably aren't either).
I had a long stint where I was trying to fix some design time behavior issues (which are VS problems such as non-response to OnSystemColorsChanged, OnSizeChanged, OnEnabledChanged), and (this seems stupid) I found out after a while that it was impossible the development environment was working off my many revisions of code. I had crossed some documentation warnings that told not set some project option, but evidently that was a deprecated option from earlier VS -- before I was using VS. Just the same, my projects were working like all the designer versions had been cached, and my changes had no effect.
I switched to totally non-visual design for several days, and when I came back, new code was honored consistently. But damn if I can tell what the heck was going on for a while. I wasted half a day's work at least just wrestling with issues I had no control over.
I'm wondering now that it didn't have something to do with a DefaultValueAttribute I had declared on an outer class property, that I later found by much experimentation could only be declared on the properties of the inner property class. I worked that out (and had much misbehavior while I was trying do use that outer DefaultAttribute), and haven't returned to it. No problem since.
Pretty strange. I don't feel like I'm out of the woods yet.
|
|
|
|
|
mike montagne wrote: Way to go, Scott.
Thanks! I'm glad I was able to get this working the way I wanted.
mike montagne wrote: I've had some other problems with VS as well -- all related to component development situations. I'm not sure I'm dealing with them the best way (you probably aren't either).
I'm sure we're not. It seems like there is still a lot of undocumented aspects when dealing with the designers and design-time behavior once you get past anything rudimentary.
mike montagne wrote: Just the same, my projects were working like all the designer versions had been cached, and my changes had no effect.
I think this is the situation that I was running in to as well. I discovered it when one the automatic updates rebooted my computer. When I came and restarted VS, things were working the way I had expected them to, even though I hadn't started changing any code yet. That's when I realized that it must have had to do with VS being shutdown.
mike montagne wrote: Pretty strange. I don't feel like I'm out of the woods yet.
I know that feeling. After I integrated this code in with the rest of the component, my RTL handling stopped working correctly. It displays fine at run-time but not at design time. That's my task for tomorrow morning...figure out what broke between the simple LabelProvider class and the more extensive class that will be used in the application.
The only thing I don't have working that I would like to is support for an ImageList (actually the ImageKey and ImageIndex properties specifially) for the label itself. That and figuring out how to make the property grid realize the additional Font property on the extended control already has it's default value. (It does the right things, it just displays it in bold showing that it has changed from the default when it really hasn't.) Both of these are minor and only affect the design-time experience so I'm not going to put much effort into worrying about them.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Scott Dorman wrote: I know that feeling. After I integrated this code in with the rest of the component, my RTL handling stopped working correctly. It displays fine at run-time but not at design time. That's my task for tomorrow morning...figure out what broke between the simple LabelProvider class and the more extensive class that will be used in the application.
In my case I can say this... there was a lot of experimenting I had to do, and, in the end, I can see why they want you to do things the way I found you had to do them. It was way too painstaking though to have to solve these wee little, almost unexplainable issues, until, one after another, you have every little detail worked out (which of course is something you have to do anyway), and finally the misbehavior goes away. What I think is going on is there are many conditions which are not handled -- which just fall through the cracks without upsetting anything -- and you *could* go on developing a bad component if you aren't a perfectionist. But it's way more difficult to get there sometimes, and that's really too irresponsible of them for my tastes. I don't like being a guinea pig, when my work is better than theirs is!
I would bet that your situation is the same... that you are going to have to chase out some things which really aren't necessarily the wrong way to do something, and which are in keeping with the language specs, but which somebody didn't decide to support in a bullet proof way.
It's pretty esoteric material to ponder, when you find after too many days work that you can't fire accessors in a class property supported by a TypeConverter -- and that you can only declare DefaultAttributes on the accessors of the inner property class.
Scott Dorman wrote: The only thing I don't have working that I would like to is support for an ImageList (actually the ImageKey and ImageIndex properties specifially) for the label itself. That and figuring out how to make the property grid realize the additional Font property on the extended control already has it's default value. (It does the right things, it just displays it in bold showing that it has changed from the default when it really hasn't.)
It looks like we're covering a lot of the same ground with our projects. I looked at ImageList and decided I wanted to handle my graphics myself. It turned out this was even easier than I anticipated. Most of this C# has been (for which too it should be praised). I'm glad I did it the way I did now. The only quirk I ran into is I found that you can't (or I couldn't) create a null bitmap property, or allow anyone to assign null to a bitmap property. When they make the assignment, handle it in your accessor and if the assignment is null, create a new bitmap of size 1,1. Initialize the property to a new bitmap of 1,1 as well.
I know that an ImageList has one theoretical advantage -- that if you want to use an image multiple places, you can do so from the one instance as you can from a compiled, embedded resource. But I decided to let them do it that way if *they* want to, and to manage my images/glyphs myself. I'm happy with that as a solution.
|
|
|
|
|
mike montagne wrote: In my case I can say this... there was a lot of experimenting I had to do
I got lucky with finding this particular issue. As I was comparing code between the simple LabelProvider (which worked) and the one that didn't, the only difference was in my "remove" method (which runs when the extender is removed or the extendees handle is being recreated). In the one that worked, I had this line: this.label = null; while in the one that didn't I had this.label.Dispose(); . Once I changed it, everything started working again. It would seem that in my cleanup I got a little too aggressive about making sure resources were being released.
I completely agree about needing to be a perfectionist to get this working correctly. I think the design capabilities of the runtime are incredibly powerful and equally as complicated. It seems like they had an idea that people would want to use it, but never really had time to completely finalize everything. So we are left with a lot of things that don't work *quite* right unless all of a certain set of conditions are met, and, of course, those conditions aren't fully documented anywhere.
mike montagne wrote: It's pretty esoteric material to ponder, when you find after too many days work that you can't fire accessors in a class property supported by a TypeConverter -- and that you can only declare DefaultAttributes on the accessors of the inner property class.
Absolutely. I've learned more details about how the Framework does things related to UI in the last two weeks than I have in several years...and all of it from trial and error.
I did implement the ability to set a single image to be associated with the label (same behavior as the normal Label control) and that works just fine, but I wanted the ability for the ImageList specifically so I could specify it in one place. For the UI that is being built that will use this component, that capability makes a lot of sense. I think everything was working properly, I just didn't have the nice design-time experience of being able to set the image using a dropdown that showed all of the images in the list (like the Label does).
I've found that there are a lot of things that are going on behind the scenes with the designer experience that don't exactly follow the model Microsoft is espousing for the rest of us.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Scott Dorman wrote: Absolutely. I've learned more details about how the Framework does things related to UI in the last two weeks than I have in several years...and all of it from trial and error.
Yes. The bandwagon believes all these things are easy. In truth it often takes the greatest expertise, ability, and effort to make some of the most simple things work.
Scott Dorman wrote: I've found that there are a lot of things that are going on behind the scenes with the designer experience that don't exactly follow the model Microsoft is espousing for the rest of us.
Absolutely.
Something I think they need to do is make developers document all this stuff, because it is very often only in doing so that you realize what too complicated a world you are building (and never documenting, so that people "don't find" the flaws in it).
The truth is, because of all that is wrong and is never resolved, probably 80%+ of the overhead invested in *good* designs is in all these unnecessary trials. I have right now about 10 weeks in a project I wrote the first time in just a few days. There was nothing wrong at all with the first design. It was perfectly straightforward, and efficient.
But it didn't draw to my standards, and I re-wrote it again and again and again, until I developed an extremely refined/optimized automatically forking (intelligent behavior) method of drawing (still not up to C++ standards, thanks to the expectable inferiority of .Net).
OK, so that's fine. But then there's all these inconsistencies in the development environment... so out of all of it I still have 80%+ of my time in fussing (too nice a word) with stuff that none of us would have to fuss with if the people building the tools built them to the standards that we are building product to.
|
|
|
|
|
Scott Dorman wrote: I've found that there are a lot of things that are going on behind the scenes with the designer experience that don't exactly follow the model Microsoft is espousing for the rest of us.
Yes, and there's where we *all* have to worry about the hidden agendas which might exist. On the surface, all this is exalted as cross platform compatible. But in truth, it is these very inconsistencies which can purposely reduce competitors to dogs perpetually chasing their tails for naught, because *our work* itself is forced to comply with the inconsistencies (merely to work).
When you find you can't fire functions from outer class property accessors when the property class is associated with a TypeConverter, is your code base really written as you would want to write it for MONO?
Not at all.
So are you going to fix it for MONO, and is the promise of platform independence a reality?
Not at all.
And then, we're sacrificing speed and working within this huge extra environment for the ostensible purpose of light resource reliance?
What we really need is to C-sharpify-C++ some... deploy all these libraries from the OS... and realize the speed benefits of today instead of downgrading them (substantially).
|
|
|
|
|
Now that I've declared victory on the extender component, I'm getting ready to tackle creating a custom layout engine. Do you have anything you can point me to as a good reference? This is in a similar state as IExtenderProvider, very powerful and not well documented at all.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Damn! It's like we're walking down the same path here.
This is where I developed my alternate scheme of drawing.
I took a hard look at all this, and (believing I'm pretty intuitive about where Anders H likes to go with these design features), I decided to descend from Control so that I could do what I wanted with optimal efficiency. In other words, my interpretation of what they're doing with the external classes which provide further services to given classes, is basically a way of partitioning so that the *whole* class you are using (really) *is* not perceived to be so oversized.
My approach was to build just what needed to be built, and to leave all that extra stuff out of my landscape. Totally custom.
After all, you will probably spend more time wrestling with the huge Cadilac they built than *designing* a Porsche. I look ahead, see too many mysteries or insufficiently documented issues... ambigous issues... hidden workings... all that sort of thing, and (thinking I can build it as well as better anyway) I just tend to dispose of all that stuff that can get in the way.
In the end it comes down to this: If *you* can build it as efficiently as it can be built, then why wrestle with all this ostensibly fancy stuff with the huge footprints, when in the end it's going to slow you down so much that you're 2 steps backward (at least), and you've incorporated an eventual dinosaur that, when *they* change it, your life's work is down the tube again.
I trust my standards better than Microsoft's -- and I've already revisited those lessons far too often.
|
|
|
|
|
Just returning for a quick thought.
All this layout engine stuff is really (as far as I'm concerned) about double buffering. It is challenging to build your own scheme which gets the benefits of double-buffering. Well, that needs to be qualified -- *when* you have to do some of the things we had to accomplish.
It always comes down to one little trick: For me, it was realizing that I could cause drawing without calling Invalidate() (which I found *not* to support double-buffering across the conditions I needed support for).
|
|
|
|
|
Scott Dorman wrote: The fact that the Parent property is null at runtime is normal as far as I can tell. The other controls and extenders that I looked at also had the same problem. (I'm not 100% sure of this since it has been several days since I looked at that aspect of it, but I'm pretty sure that was the case.)
PS. None of us can be experts on everything, so the thought I pass along here must be declared to be no more than an educated assumption (based on all experience).
In every visual component design project I've seen or been involved in, null != Parent is obligatory to drawing. My thinking then is that your assumption is a dangerous one to build further work upon. In other words, you might very well waste considerable work before you find indeed that this assumption is wrong (which, without exception, is my experience).
I would absolutely get that Parent assigned, or expect the anomalous behavior you are describing. I mean... how can any process draw your label, if it doesn't even know what to draw it on?
|
|
|
|
|
I see your point. If I create a simple form with two controls on it, the Parent property is not set until the call to this.Controls.Add(...) . In my code that I use to add the label control, I have a similar line which also sets the parent property.
The code I ended up with looks basically like this:
this.label = this.provider.EnsureLabel(this.control);
this.label.Text = text;
ISite site = this.control.Site;
if (site != null)
{
site.Container.Add(this.label);
}
this.control.Parent.Controls.Add(this.label);
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
You are *exactly* right.
It is in the underlying handler for Controls.Add() that Parent is assigned -- and the scheme of the visual system is based on this interraction.
To replicate that, all you have to do with your label of course is to add it to the Controls array.
|
|
|
|
|
mike montagne wrote: all you have to do with your label of course is to add it to the Controls array.
Yes, I am doing that (last line of my example code), so it seems like that particular issue, at least, has been resolved.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
OK. What appears to be a probable problem here is that your site.Container.Add(this.label) gives one container the responsibility of painting your label. Then you are given this.control.Parent the responsibility of painting (and disposing) your label.
There's a struggle going on there that cannot be resolved, and your behavior is quite surely a result of it.
|
|
|
|
|
One other thing...
I just thought I'd mention this since your assumption reminds me of a very costly error I made recently. I was looking for documentation to resolve what I believe should have been a very simple matter -- something it should have taken only a few minutes to resolve.
Over the years, I've coached myself to do certain things whenever I encounter a difficulty. The thing I usually do here is first step back and abstract my problem to its most simple possible terms: I made an assumption. *IS* it right?
What happens when we *cannot* answer this question with *absolute* certainty is, we can pursue many trails... always having to return to this juncture unless *we just happen* to get it right. The problem *even* with "just happening to get it 'right'" is, we still don't know if we have "done it" *soundly* -- and so it is *still* necessary to return to the juncture and answer the first question *with absolute certainty*.
So, I slap myself good and hard... and bore into that first question to find the absolute answer.
I believe that will best get you wherever you are going.
On the humorous side of this... so what was my costly error recently of just this sort?
Actually, I posted a couple of questions here, and a few people tried to cite general documentation areas (which were further wild goose chases). I was a bit surprised that no one could answer my relatively basic question, but on careful analysis of product documentation I find instead that there is good reason for all of us to be as "inept" as I was to find the answer to this simple issue.
I needed to define a composite control property of a further custom class, and (of course) I wanted that class property to be displayed under a nested node in Property view.
OK. We can all say I must have been stupid, because we all know that you have to write a "TypeConverter" to do this, right?
If that were so, why was the closest thing to an answer an uncontested suggestion to write a ControlDesigner?
Here's the problem. I spent *days* carefully dissecting walkthroughs for the possible deviation I must have inadvertently committed, *even when the walkthroughs didn't even seem to be explicitly addressing my issue*.
(Well, that's "thorough," isn't it?)
Not exactly. Because I ignored my first question: Was my assumption *right*?
What was my assumption?
No search turned up nested node or pointed me to TypeConverter. I *DID* however see TypeConverter, and I did occassionally browse it a bit. But (due to the way it is written), I never saw it provided the behavior I wanted. Nor, in my wildest dreams, would I assume (particularly because no *conversion* of types should be involved whatsoever with what I wanted to do) that a "TypeConverter" would be the one vital instrument of achieving nested node behavior.
So I *assumed* TypeConverter was not a probable avenue.
Indeed, poor documentation and nomenclature both may be said to have led me astray. And too, there are too many such possible issues to explore so exhaustively (which is why documentation needs to be much better than it is), that we can and do regularly resolve so many issues as fast as we could resolve them if many details were better attended to, and if documentation systems were designed as well as they could be.
But still, my problem would have been solved much faster if I had resolved my assumption to definite terms.
|
|
|
|
|
Scott, if you take a look in the Windows Forms section, I answered this particular problem there. Basically, the problem that you are having is one to do with the sequence of events that happens when a form loads. The extender provider is associated with your component before your component is added into the controls collection, so you need to handle the ParentChanged event to capture the control being added in.
the last thing I want to see is some pasty-faced geek with skin so pale that it's almost translucent trying to bump parts with a partner - John Simmons / outlaw programmer
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
Pete,
Your explanation here is much easier to understand than the one in the Windows Forms section. I know they both say the same thing, but this one makes it much clearer. Anyway, as I said in my reply to your other message, between your posts and Mike's I was able to get this working correctly. The finishing touches go on tomorrow.
Thanks,
Scott.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Not a problem. I'm glad that I can be clear at least some of the time
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
Now that I've declared victory on the extender component, I'm getting ready to tackle creating a custom layout engine. Do you have anything you can point me to as a good reference? This is in a similar state as IExtenderProvider, very powerful and not well documented at all.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Hi all
I have Visual studio 2003 with just c# installed I have to read in a access database and show it using the smart device application. I sort of know how to do it on a normal app but as soon as i enter using System.Data.OleDb It cannot find on the smart device library. Is there way to read in a database and show it using a smart device app.
Can any one help
Thanks
James_Bond
|
|
|
|
|
|
Thanks
But you see this is using System.Data.OleDb; which is not in the smart device library so i need to use something else. if you know how to do it in smart device or someone else please help
Thanks in advance
James_bond
|
|
|
|
|