|
You can check on the type of the toolstripmenuitem. For the separator this is System.Windows.Forms.ToolStripSeparator.
|
|
|
|
|
I'm not sure about your problem, but may I ask, why not use .NET remoting? Remoting is built atop sockets, yet abstracts away the underlying byte transfers, allowing you to simply call theServer.DoSomething() on the client, or call client.DoSomethingElse() from the server.
|
|
|
|
|
Hi there,
i wonder if there is a way to include the windows-explorer in your own application.
i need the abilty to show some folders with files in my app and it´s quite a lot
of work to do the stuff with the ListView control.
is there any way to include windows explorer in my app? maybe through some kind of
activex?
thanks
jkersch
|
|
|
|
|
C# File Browser[^]
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
I am implementing a custom IExtenderProvider derived class so I can dynamically set the following properties on a control:
Required (using an ErrorProvider)
Description (ToolTip)
Errors (using an ErrorProvider)
Caption
I have everything working except for the caption. Ideally, I would like to add a Label control to the form for the given UI element. I know how to draw the label text myself, but that doesn't give me any of the accessability features that I gain when using a label.
The problem I'm running in to is that I can get the label to appear at design time but not at run time. Essentially, when I detect that a new control has been added I try to add a new label control (positioned appropriately) to the parent's Controls array. This works fine at design time but at run time the Parent property of the control I'm extending is null.
I'm trying to do this using an IExtenderProvider so I don't have to create subclassed versions of the UI controls to add a caption. In case you want the background, the project I'm working on needs to allow a dynamically rendered UI based on various pieces of meta data contained in the business object. The business object can be customized by the end-user through an admin interface, so I will never know what fields will be present and what their captions should be until it is time to actually render the screen.
Has anybody done anything similar to this? I've pretty much exhausted the information available on Google, which isn't much beyond creating a simple provider.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Without source, it will be pretty challenging to give you much help. Nonetheless, in reading your post my guess is that you have an obvious problem with the Parent that has nothing to do with IExtenderProvider.
You have to solve the null Parent issue (I assume) to parent your Label. Without a parent, the Label will never be drawn.
So to fix your issue, you need to build a scheme to precipitate parent from a source value somewhere.
|
|
|
|
|
mike montagne wrote: Without source, it will be pretty challenging
I completely agree. Unfortunately I'm not able to post source for this. (I am actually trying to get approval to do this as an article (or at least a simplified version) since there seems to be a need for it.)
Since I posted I stumbled across a partial answer to this problem. I am now able to get the label to persist and generally behave properly with one exception. When I first put the extender on the form and start adding labels, none of them appear on the design surface until I close the form and re-open it. I haven't tracked down the reason for this yet.
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.)
I hope to get approval to do an article based on this work for at least a LabelProvider type control soon since I am digging semi-deeply in to how the designer works and how to manipulate properties using the design-time services.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Scott Dorman wrote: Since I posted I stumbled across a partial answer to this problem. I am now able to get the label to persist and generally behave properly with one exception. When I first put the extender on the form and start adding labels, none of them appear on the design surface until I close the form and re-open it. I haven't tracked down the reason for this yet.
You probably realize this... but the reason is *always* that your algorithm hasn't triggered drawing yet. It is closing the form and re-viewing/restoring it that triggers an invalidate -- which finally gets your labels to draw.
|
|
|
|
|
mike montagne wrote: You probably realize this... but the reason is *always* that your algorithm hasn't triggered drawing yet. It is closing the form and re-viewing/restoring it that triggers an invalidate -- which finally gets your labels to draw.
Yes, that is the premise I am working under. Currently, I am attempting to resolve this by calling Invalidate myself, on both the label and it's parent control but so far it isn't having an effect.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Interesting... because I've had some similiar issues with a visual control project I'm currently working on. I have quite a bit of time in developing a (proprietary) scheme which ensures that drawing is performed. (Can't share it, sorry. But you can get there too.)
A related issue for instance demonstrates to my satisfaction that there are problems with compiler output. I find some overridden event handlers such as OnSizeChanged() are correctly fired. But I find others such as OnSystemColorsChanged() and OnEnabledChanged() are never fired!
OK. So we can fix OnEnabledChanged() because we can write a new Enabled property. But we can't fix OnSystemColorsChanged() because there is no way for us to detect *and* fire the outer system event.
So, I called Microsoft about this, explained these issues for about an hour, and they wanted to charge me $249 to report them... to which I replied I wouldn't give the 2 cents to report them... I'd be more inclined to initiate a class action suit if they had so little concern about fixing all these things.
That's of course another matter, and neither are the non-fired events exactly your issue. They are surrounding issues which tell us we are not working in a perfect environment. I don't believe we should simply accept these things, because if you and I are to succeed, not only do we have to do far more work than we should have to, we have to do our work to a substantially higher standard than the authors of the tools.
It's possible you have committed a relatively obvious ommission or failed to perform a responsibility. Otherwise, the challenge is devising a sound scheme which ensures your drawing is performed when it needs to be.
|
|
|
|
|
I'm not sure I will need to go to the level of developing a completely custom scheme since I'm not actually creating a new control type. It is interesting to know about the event handlers not being raised. I don't think I will encounter that problem as there are very few events that I should actually need to listen for.
I'm a little surprised that Microsoft wanted to charge for reporting the bugs.
I do completely agree with you in that we aren't working in a perfect environment. I think the problem is that a lot of people don't need to dig this deeply into these types of behaviors/development tasks so the visibility to some of these types of problems is relatively low.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
I was *more* than a little surprised...
Anyway... custom schemes are required when we want to dispense with the baggage given to a higher-level control which for instance supports substantially extended behavior in suspend and resume layout, by descending from a lower-level class such as Control. You are on your own then, and (as with OnSystemColorsChanged()) I found that Invalidate() will not always invoke a re-drawing, but that I could force IL to respect Invalidate() always, by ensuring that IL recognized that something *needed* to be drawn.
|
|
|
|
|
The strange thing here is that once the label is displayed (by closing/opening the form) it shows up in the designer visually, in the designer Properties window, and I can interact with it. However, there is no code present for it in the Designer.cs file. If I further customize one of the label properties directly, I do get code in the Designer.cs file. Even with no code in this file, everything still behaves correctly at run-time and design-time.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
Yes, that's definitely strange, because without a parent, drawing algorithms should have no idea even where to draw the control (where the coordinate system starts, etc.)
It is possible that an assumption is made, not in performing your constructor (which would perform the initial draw which is failing), but in repainting all the existing controls (which may explain the later appearance, for instance when you collapse and restore the IDE window).
What may be happening there is that the coordinate system is simply assumed to be the design window, and your control is painted *over* it. In other words, it may be painted as a separate, unparented windowed control, floating over your design surface.
|
|
|
|
|
Hmmm...I see the point you are making, but it doesn't answer the issue of the Designer.cs file not containing any code for the label control even though it is visible in the design surface and I can interact with it.
-----------------------------
In just two days, tomorrow will be yesterday.
|
|
|
|
|
No, if the control is painted *over* the window, even if it is erroneously attached to the design window's coordinate system), and if the control is dynamically assigned a parent after design time processes would normally attach it to a parent (which triggers membership to the form code body), this would engender exactly the results you report.
|
|
|
|
|
(This also means that designers are not an issue.)
|
|
|
|
|
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.
|
|
|
|
|