March 2003 - Posts
Ok, so I started actually using my recently mentioned form state persistence
component, and i unfortunately found what seems to be a bug in vstudio.
The component checks its DesignMode property for false before it tries to do
its thing, even before it actually associates itself with the form in the .Form
property's set accessor.
So I drag the component on a "base" form for the app, and all is well.
However, when I derive from that base form and try to open the derived Form
in the designer, vstudio just gives me a crappy "there was an error "... blah
blah blah. After a while of sniffing around, I attached another instance of
vstudio and debugged when I opened my child form in the designer.
It seems that there is a bug where, when you have a form inherit from another
form, the base form is not set to be in design mode, and neither are any
components that exist on the base form. OOPSIE.
So I wrote a horrible hack that catches an exception from a call to
Application.CompanyName. This will throw an exception at DesignTime, because it
tries to get the CompanyName of devenv.exe, and devenv.exe isn't a .net app.
Anyway, if anybody was already using it, go get the Latest
Version
I don't make very many winforms apps in my free time,
but for those who are making them, I have a little assembly that you may be
interested in.
It started when a user wanted the application to remember where he placed the
form and how big it was between starts of the app. A pretty reasonable request,
I thought.
I figured, I'd just create a state persistence component that I drop on the
base form class that all my app's forms derive from, and it'll be done. I
figured that this component has probably already been written somewhere.
What I found is that there weren't any that didn't require ( at least ) some
code to be written to get it to work. I wasn't happy with that, so I figured I'd
just write my own.
I started off just writing a component, but found that the Component class
doesn't have a way of automaticly knowing about the form it has been dragged
onto. This makes sense, as most components have nothing to do with forms. I
figured I could use Control, but I wanted to keep my component non-visual, and
living in the component tray in vstudio. What I wanted was a mid-level object
between Component and Control. Unfortunately, no such class exists. So I created
one.
Say hello to FormComponent. When dragged onto a windows form, it overrides
the normal InitializeComponent code-serialization process and adds a line of
code which sets the current form as the component's Form property. Once this
piece of magic is in place, components that want to access the current form
don't have to rely on the developer to write code hooking them up.
So now writing the state persister is trivial. I simply subscribe to some key
events, Load, Resize, Move, and Closing, to load, track, and save the state of
the form to xml in the user's app data folder.
anyway, enough jabbering, here's the link to the form state
persister and base FormComponent class, for easy creation of similar
form-oriented components. In the download is the full solution source code in
C#, a precompiled version for those who just want to use it, and an example
application
with 1 form that persists its state.
I hope yall like it, have fun.
The more that I actually got to the nuts and bolts of
created an extended checkboxlist which selected items based on a
DataSelectedField, the more i didn't want to bother. Because of the way
ListControl overrides OnDataBinding to do its thing and the way DataBinding is
implemented, I can't raise the DataBinding event without accessing private
fields on the control class. grr.
This means i'd have to either break the "rules" of encapsulation, or
completely reimplement ListControl AND CheckBoxList to add this feature. grr
grr.
I'd also have to copy/paste ( AGAIN ) an implemention of what
DataSourceHelper.GetResolvedDataSource does. for the love of GOD why was that
marked internal?
It seemed like such a simple idea at the time, but implementation choices of
the base controls made it much harder than it should be.
I'd basically have maybe a hundred lines of re-implementation for ~4 lines of
actual extension.
meh.
please don't take this as a condemnation of the web controls guys. Overall
they did a great job of allowing for extension of the control library. It's just
that sometimes you hit a wall, and there's no happy way around
it.
I was thinking about the CheckBoxList control today, and
it hit me that while you can set the DataTextField and DataValueField
properties, a really useful one would be a DataSelectedField property, which
pointed to a boolean field in the row which indicated the Selected property of
the ListItem, which would translate to the Checked property of the checkbox.
To implement that, I'll probably have to subclass CheckBoxList and
reimplement DataBind. At first I thought I could just override it, and run thru
the datasource again, but then I thought about the scenario where people bind to
DataReaders, which can't be read thru twice. So I guess it's up to me to
reimplement the whole function.
What would have been useful is if the DataBind method seperated out the
itteration of the datasource, with the application of each item's
information. Something along the lines of a protected virtual method that got
passed one item from the enumeration and the ListItem to be affected.
I realize it wouldn't make much sense for the basic implementation of the
control, but it's really really usefull for somebody extending the control.
I'm thinking I might even make an event for this, so that others could even
more easily extend it to allow for setting colors or whatever based on the
ListItem and currently enumerated data object/row.
I have a new control
up on metabuilders. It's a radiobutton that has a global GroupName. This lets
you put it in a repeater or usercontrol or whereever, and the GroupName will
still work. I threw it together in a few hours, but it was a bit harder than it
should have been, as I had to completely reimplement RadioButton. ( please, MS,
give us more protected virtual methods, please )
It works by using the GroupName as the name attribute, totally disregarding the
unique id's generated by being in naming containers.
On a bit of a rant... Hotmail has officially annoyed me. I have
a subscription/notification thingie on my website where I send people email
when the site gets updated, but hotmail decided that my email is spam and so just bounces
it. Grr. Of course i could play the same games that the real spammers do...
changing subject lines and such, but dammit, I shouldn't need to play games to
send an email.
So anyway, if you signed up on my site with a hotmail address, sign up again,
but this time with a "real" address. I'm sorry.
Ok, here's the deal... I've had an asp.net PanelBar control
( like the outlook sidebar ) "done" for a VERY long time. The problem is that
the design-time experience is horrible. The templates don't seem to work...
various properties seem to disapear randomly... but only
in visual designers of vstudio or webmatrix.
The question is... should I release it in it's current state? The only reason
I'd consider releasing it is because the problems only exist in the designer.
It's perfectly usable be everybody who doesn't use a designer.
(Note, the example page I have there currently isn't sending down the client
script that would avoid page postbacks for changing the selected item, this is
because I'm lazy and haven't gotten around to flipping that boolean
)
For those of you who don't know who the hell I am... I run metabuilders.com, spending a good chunk of my time developing asp.net controls for the community.
I also recently released Nebo, an irc library that I've been working on for quite a while now. I'm sure it's got a few bugs running around, but hey, i won't find them until I get a wider testing base.
Anyway, I'm really looking forward to giving you a glimpse behind metabuilders.
More Posts