Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Overriding a property is not working.

9 views
Skip to first unread message

Dom

unread,
May 17, 2012, 10:44:12 AM5/17/12
to
I guess I don't really understand how "override" works with
properties. For various reasons, I've created a JournalListBox
control that inherits ListBox. This control has a List of
"Journals" (over 6,000 items), but the journals do not show up in the
listbox. Instead, as the user types, the list box shows a set of only
12 appropriate items. For example, if the user type "J", then the
JournalListBox shows the first 12 items that begin with "J", and so
on.

I decided to override the SelectedIndex property. The user can set
the SelectedIndex to, say, 4397. The JournalListBox translates this
into the appropriate number between 0 and 11, then sets that number.
Here is how it looks:
----------------------------
public override int SelectedIndex
{
get
{
if (base.SelectedIndex == -1) { return -1; }
else { return (base.SelectedIndex + StartIndex); }
}
set
{
if (value == -1) { base.SelectedIndex = -1; }
else { base.SelectedIndex = (value - StartIndex); }
}
}
----------------------

"StartIndex" is, of course, the index into the Datalist that appears
as the first item in the listbox.

Some problems:
1. I know from debugging that when the setter is called, it in turn
calls the getter. Why?
2. If in the immediate window I request base.SelectedItem, it calls
the getter. Why? I thought it would only call the getter if I
requested this.SelectedItem.
3. Since base.SelectedItem calls the getter, and the getter calls
base.SelectedItem, why am I not caught in an infinite loop?

TIA,
Dom


Dom

unread,
May 17, 2012, 11:09:55 AM5/17/12
to
As a test, I decided to change "override" to "new". It works now.
This makes me think that the error is occuring somewhere else, like in
the designer for the JournalListBox class. Am I right to think that
"override" should work for me, and is the preferred approach?

Dom

unread,
May 17, 2012, 12:18:45 PM5/17/12
to
> "override" should work for me, and is the preferred approach?- Hide quoted text -
>
> - Show quoted text -

Does it matter that JournalListBox is not a UserControl, but is a
Custom Control? If so, I have to admit, I never knew the difference
between the two. I always used the rule : A UserControl is one that
has several components, eg, a text box and a listbox; and a Custom
Control is a control that has new methods and overrides.

Peter Duniho

unread,
May 17, 2012, 6:36:43 PM5/17/12
to
On Thu, 17 May 2012 07:44:12 -0700 (PDT), Dom wrote:

> I guess I don't really understand how "override" works with
> properties. [...]

Short version: declaring the property with "override" causes the two
property methods (the getter and the setter) to each themselves be
overrides of the base property methods.

> [...]
> Some problems:
> 1. I know from debugging that when the setter is called, it in turn
> calls the getter. Why?

I haven't looked at the code, but one obvious explanation is that the
implementation may compare the new value with the current value, so that
certain things happen only when the value actually changes.

> 2. If in the immediate window I request base.SelectedItem, it calls
> the getter. Why? I thought it would only call the getter if I
> requested this.SelectedItem.

Because you only get non-virtual dispatch for the method you're actually
in. I'm a little surprised the debugger even allows "base.SelectedItem" to
be retrieved while the setter is the current method, but given that it
does, it's still not that surprising to me that you'd still get the fully
virtual dispatch of the method.

> 3. Since base.SelectedItem calls the getter, and the getter calls
> base.SelectedItem, why am I not caught in an infinite loop?

That's too imprecise a question to answer. There is no "base.SelectedItem"
per se. When you declare a property, you wind up with two methods in the
type. For example, "get_SelectedItem" and "set_SelectedItem".

Infinite loops certainly are a risk, but the getter shouldn't be calling
the setter, so even if the setter calls the getter, that wouldn't cause an
infinite loop. Similarly, using "base.SelectedItem" to achieve non-virtual
dispatch calls a different method than yours; as long as that doesn't in
turn wind up calling your own implementation again (and why would it?),
again no infinite loop.

Pete

Peter Duniho

unread,
May 17, 2012, 6:39:08 PM5/17/12
to
On Thu, 17 May 2012 08:09:55 -0700 (PDT), Dom wrote:

> As a test, I decided to change "override" to "new". It works now.
> This makes me think that the error is occuring somewhere else, like in
> the designer for the JournalListBox class. Am I right to think that
> "override" should work for me, and is the preferred approach?

Define "works now". What wasn't working before? You didn't actually
describe any real problems in your previous message.

I'm sure that by hiding instead of overriding the base property, that some
of your tests behaved more to your liking. But using "new" means that your
own implementation will be called only by code that is calling through a
reference statically declared as your own type. In particular, none of the
base implementation (such as that which responds to user input) will go
through your own code.

As far as I can tell from your description, you really do want to override
the base implementation, not hide it with "new".

Pete

Peter Duniho

unread,
May 17, 2012, 6:43:04 PM5/17/12
to
On Thu, 17 May 2012 09:18:45 -0700 (PDT), Dom wrote:

> Does it matter that JournalListBox is not a UserControl, but is a
> Custom Control? If so, I have to admit, I never knew the difference
> between the two. I always used the rule : A UserControl is one that
> has several components, eg, a text box and a listbox; and a Custom
> Control is a control that has new methods and overrides.

Your understanding was (and is) correct. The UserControl type is
specifically a container type that allows aggregation of other controls.
Its primary advantage is to allow the use of the Visual Studio Designer to
create such aggregates, just as you would a Form subclass, but in a control
type that can be placed within other controls.

There is no "Custom Control" type per se of course, but that is indeed the
template type you'd choose from the "Add to Project" interface if you want
a single, simple custom control. Likewise, such as in your scenario where
you are overriding an existing control type, one easy way to do that is to
start with the "Custom Control" template, and then modify by hand the base
class, changing it from "Control" (which is the default) to whatever type
you actually want to override (e.g. "ListBox"). Just remember to change it
in the main .cs file as well as the .Designer.cs file.

Pete
0 new messages