.NET Forum / Windows Forms / WinForm General / July 2006
usercontrol with readonly property that can be set at design time
|
|
Thread rating:  |
mmcd79@tampabay.rr.com - 09 Jul 2006 00:19 GMT Can someone tell me if it's possible to create a property for a usercontrol, that is essentially readonly, but able to be set via the designer before runtime?
I have a property for a control that I want to set essentially one time. This property is basically a static property that can change at the developer's wish, but only one time. I need to be able to reference the property later.
I've tried setting the property to readonly, but that hides it from the designer properties window. I've tried various attributes to no avail (i.e. DesignOnly(true)). When I do this, I cannot set the property at design time(the value doesn't hold). But in later code I can change that property without fail.
I'm confused. Please help.
Joris Zwaenepoel - 10 Jul 2006 12:38 GMT Not the most elegant solution, but I guess you could throw an exception if the property is set in runtime (code not written in IDE, so not tested, and could have syntax errors).
Public Property MyProp As Integer Get Return _myProp End Get Set(ByVal value As Integer) If Me.DesignTime Then _myPorp = value Else Throw New ApplicationException("MyPorp is readonly in runtime.") End If End Set End Property
Joris
> Can someone tell me if it's possible to create a property for a > usercontrol, that is essentially readonly, but able to be set via the [quoted text clipped - 12 lines] > > I'm confused. Please help. Stoitcho Goutsev (100) - 10 Jul 2006 22:45 GMT Hi,
No attibutes will help you with that. DesignOnly attruibute won't help because as the name suggests the values for such a property are design time only - no code is generated in the form or user control to restore set up such properties at runtime. The values are stored in the resource file and are use at design time only.
If you declare the property as readonly or use readonly field it won't do either. Don't forget that what ever you set in design time needs to be applied in runtime and this is done in the IntializeComponent method. From the CLR perspective this is just a method, so it has no power to set non-writable or non-public properties and fields.
I see two solutions: 1. (that I'd suggest) is to use some variation on the Joris code.
I say variation becuse this code has one big flaw - when you run your applicaiton the InitializeComponent will try to set the property and at this moment DesignTime will return false and the control will throw an exception. You should probably have some special value for this property that will tell you whether the property is already initialized or not and will allow to be initialized only once.
2. If you have a designer attached to your control you can shadow your readonly property with read/write one, thus allowing users to set its value. Then you need to supply your own CodeDomeSerializer that will generate appropriate code to set somehow that property. Of course you need to have some backdoor open for setting this proeprty such as an undocumented method.
There is something that bothers me though. You say that this is going to be a static property. If it is exposed on the level of the control there might be 2 or even more instances of your control on the form. Each of these controls will try to set the static property. If using the first solution you are going to get an exception as soon as the second control tries to set it.
 Signature Stoitcho Goutsev (100)
> Not the most elegant solution, but I guess you could throw an exception if > the property is set in runtime (code not written in IDE, so not tested, [quoted text clipped - 33 lines] >> >> I'm confused. Please help. mmcd79@tampabay.rr.com - 11 Jul 2006 02:35 GMT Thank you both for responding :)
I did not think this was going to be such a difficult thing to do haha. Maybe I'm just going about it the wrong way. I'm not the most intuitive/knowledgable coder. This is just hobby for me.
I'm essentially writing a form of a wizard. I have a navigation panel that currently contains several labels that have click events to control which wizard page I'm on. All of my content pages are custom usercontrols (which make no difference here).
Ultimately I'm trying to find out which label was clicked and show the appropriate content for each label. My previous thought was to attach a page property for each label (which in turn makes this a custom label with this additional property and as such the purpose behind my entire question). Any additional customlabels added (in the future) could just have the next page value set (by developer) and then tied to corresponding "content page".
I don't want to do any sort of case statement based on the control name/text as this leaves no room for growth. Any developer picking this up after me may modify the names/text of these labels to something more meaningful so I want the properties to at least be a little more meaningful in terms of their purpose and lenient in terms of these changes.
I could just do this with a normal property, but I didn't want someone changing the page values of the controls programmatically after they have first been set. Just trying to figure out the "best" way to do this, not some ugly hack if at all possible.
I appreciate the assistance given thus far and look forward to more suggestions.
> Hi, > [quoted text clipped - 73 lines] > >> > >> I'm confused. Please help. mmcd79@tampabay.rr.com - 11 Jul 2006 02:44 GMT hahaha.. I'm such a retard. I'm researching all over to find out what the "Joris Code" is as I sitting here thinking it's some well known coding methodology. I couldn't find anything on it. Then I think, "Self, he mentions something that the previous poster said as well. Low and behold his name is Joris. *sigh*
I have seen several implementations of Joris' suggestions and some of them have had an additional property, or private member so to speak that tracks if the property has been set or not. Wasn't sure if that'd be a good way to go. Guess I'll give it a shot.
Thanks again!
mmcd79@tampabay.rr.com - 12 Jul 2006 02:08 GMT I have set the following, but I'm still having an issue. -------------------------------------------------------------------------------------------------- Public Property WizardPageNumber() As Integer Get Return _WizardPageNumber End Get Set(ByVal value As Integer) If Me.DesignMode Then Debug.WriteLine("we're in designmode") 'check to see if wizardpagenumber has already been set. If so, throw exception alerting developer 'that this property can only be set once. If Not _PageIsSet Then _WizardPageNumber = value 'set page value _PageIsSet = True 'set tracker variable to prevent further setting of this value. Else Dim ex As New Exception("WizardPageNumber can only be set once.") Throw ex End If End If End Set End Property --------------------------------------------------------------------------------------------------
If on a form I drop this control on the form, I can set the property once via the designer. Any subsequent settings will raise an exception. Super.
Now the problem I have is say I set the initial value to 5. Then as a test set the property to a different value, say 3, during the form load event. If I run a check for the value before and after setting it to 3, I get no exception, and both before and after the value is stuck at 0.
I'm assuming the inability to set the value is due to the "if me.designmode" declaration. Any suggestions for this?
> hahaha.. I'm such a retard. I'm researching all over to find out what > the "Joris Code" is as I sitting here thinking it's some well known [quoted text clipped - 8 lines] > > Thanks again! Joris Zwaenepoel - 12 Jul 2006 07:26 GMT I suggest you step through the code in runtime, and you'll see what is wrong.
When not in "designmode", the value is not saved in the variable. Yo ushould change you code as follows, to allow the property to be set in runtime:
If Me.DesignMode orelse Not _PageIsSet Then _WizardPageNumber = value _PageIsSet = True Else Dim ex As New Exception("WizardPageNumber ....") Throw ex End If
Joris
> I have set the following, but I'm still having an issue. > -------------------------------------------------------------------------------------------------- [quoted text clipped - 47 lines] > > > > Thanks again! mmcd79@tampabay.rr.com - 13 Jul 2006 02:02 GMT Thanks Joris. I guess you could say that worked, although now I'm thinking I really should do this a different way haha. The exception works fine in the designer but it really causes some interruption during runtime, obviously due to the exception I throw. I'd end up having to do some exception handling in designmode vs realtime mode to prevent total breakdown at runtime, and it's just getting too ugly.
I really appreciate the help and the insight into using shortcircuiting. I never even thought of that. Nor did I even think to try debugging :-x. I think it's cuz I knew the designmode if block woulda been skipped during runtime. Denial I guess :).
Since I cannot think of an elegant solution to this I think I'm going to just use a normal public property and let the developer know via comment that setting this value more than once in code could wreak havoc.
Another ugly thought, is there any way via reflection to possibly get the calling procedure? Maybe I can limit the value to be set during it's initialization phase so it can be set all it needs in the designer (as it automatically generates that code), and then throw an exception if it's tried to be set in any other procedure.
Thanks guys!
> I suggest you step through the code in runtime, and you'll see what is wrong. > [quoted text clipped - 63 lines] > > > > > > Thanks again! Joris Zwaenepoel - 14 Jul 2006 09:10 GMT I don't think this could cause much "interruption during runtime". The property should never be set during runtime anyway (you wanted a read-only property), so if you do try to set it, you get an exception the very first time you test that code, and the exception message should be meaningful to the developer, so that he understand what is wrong. Then the developer fixes his code, and there are no more "interruptions at runtime".
Also, you could modify the property setter to not throw an exception, but also not modifying the value of the property if it has been set before. That would prevent the "interruption" but it would be very confusing for the developer who tries to set the property, does not get an exception, but notices that it does not work the way he expected. (Maybe a "debug.Assert" could help, but only if the code is compiled in debug mode.).
Joris
> Thanks Joris. I guess you could say that worked, although now I'm > thinking I really should do this a different way haha. The exception [quoted text clipped - 88 lines] > > > > > > > > Thanks again! mmcd79@tampabay.rr.com - 17 Jul 2006 00:14 GMT I probably said it wrong. I'll try to clarify what I meant. With the code that I had, if the developer tried to set the code during design time via the designer, the exception worked wonderfully.
If the developer tried to set the value elsewhere in code, the exception wouldn't be thrown until runtime when the value would try to be set.
What worries me in this scenario is say the developer set the value in code, but in such a way that it wasn't set on load or any other immediate time. Maybe it was a reaction to some other function that never got called until well after the app was loaded. He may not get a chance to "test" that functionality as the app loaded fine. The app would be deployed and then someday as the app's being used, a horrible exception gets thrown due to the developer's oversite.
Granted proper debugging of the entire app would help prevent this, but most people don't do that, especially in my company. I'm trying to prevent as much as possible since our normal "developers" aren't really taking the time to do things right haha.
I hope that explains my worry and doubt for this method. I need a true readonly property, but I need to be able to set it. Hopefully I'm not just missing what you're saying.
> I don't think this could cause much "interruption during runtime". The > property should never be set during runtime anyway (you wanted a read-only [quoted text clipped - 104 lines] > > > > > > > > > > Thanks again!
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|