What does this mean [DefaultValue(false)]

T

tony

Hello!!

I have some demo programs written in C# and they have this construction
"[DefaultValue(false)]" see below.
I haven't seen this before so what does it mean ?

[DefaultValue(false)]
public bool ShowDropDownButtons
{
get { return showDropDownButtons; }
set
{
if (showDropDownButtons != value)
{
showDropDownButtons = value;
base.OnChanged(InvalidationMode.ColumnWithoutHeader, false);
}
}
}//end property ShowDropDownButtons

//Tony
 
M

Marc Gravell

It simply tells the system what the default value is *for things that
respect DefaultValue*; typically used by the designer (for controls) to
avoid putting in unnecessary lines into InitializeComponent, but this is
also used in WSDL (it makes the property optional with a default) and a few
other places.

Note that this is not /quite/ the same as having a default (ctor etc) value
against the underlying field, as external components don't have (legitimate)
access to the field. It really just formalises it for use by external code;
note that it would be quite unusual to have a DefaultValue that didn't match
the underlying fields defaulted value...

Marc
 
J

J.Marsch

I agree with what Marc wrote, just making some additional comments:

the DefaultValue attribute is just markup to tell external code what the
default value of a property is supposed to be -- it does not actually affect
the initial value of the variable.

Why this is interesting:
It allows for some optimizations. For example, in the code that you posted,
if you drop the control on a form, and leave ShowDropDownButtons set to
false, then the Visual Studio form designer will not add initialization code
to set ShowDropDowns to false (because it understands that it will start
out false anyway). That means that there is one less line of code to jit
and execute when a form is initializing.

If you have a form with a lot of controls, and all of the controls include
DefaultValue attributes, you can cut down on the load time of your forms a
bit.
 
T

tony

Hello!!

Here I have the class called DynamicallyColumn. What will be the difference
if I remove this statement [DefaultValue(false)]?
I have made some tests this property showDropDownButtons is false even if
you have this statement [DefaultValue(true)] or
remove the initialization on showDropDownButtons to false.
So this has no affect on the initialization.

So I still don't understand what it's purpose is. You mentioned something
about optimization. Can you explain that?

public class DynamicallyColumn : DynamicallyAutoDetectDataTypeColumn
{
private bool showDropDownButtons = false;
public DynamicallyColumn(string titel ) : base(titel)
{
this.showDropDownButtons = showDropDownButtons;
}

[DefaultValue(false)]
public bool ShowDropDownButtons
{
get { return showDropDownButtons; }
set
{
if (showDropDownButtons != value)
{
showDropDownButtons = value;
base.OnChanged(InvalidationMode.ColumnSummary,
false);
}
}
}
}

//Tony


J.Marsch said:
I agree with what Marc wrote, just making some additional comments:

the DefaultValue attribute is just markup to tell external code what the
default value of a property is supposed to be -- it does not actually affect
the initial value of the variable.

Why this is interesting:
It allows for some optimizations. For example, in the code that you posted,
if you drop the control on a form, and leave ShowDropDownButtons set to
false, then the Visual Studio form designer will not add initialization code
to set ShowDropDowns to false (because it understands that it will start
out false anyway). That means that there is one less line of code to jit
and execute when a form is initializing.

If you have a form with a lot of controls, and all of the controls include
DefaultValue attributes, you can cut down on the load time of your forms a
bit.


tony said:
Hello!!

I have some demo programs written in C# and they have this construction
"[DefaultValue(false)]" see below.
I haven't seen this before so what does it mean ?

[DefaultValue(false)]
public bool ShowDropDownButtons
{
get { return showDropDownButtons; }
set
{
if (showDropDownButtons != value)
{
showDropDownButtons = value;
base.OnChanged(InvalidationMode.ColumnWithoutHeader,
false);
}
}
}//end property ShowDropDownButtons

//Tony
 
M

Marc Gravell

It only affects *things that use this control* (via the IDE).

IIRC, it goes like this:
* You drag your shiny new control onto a form
* It runs the default ctor, which defaults (via the field default) to false.
***THIS IS THE IMPORTANT ONE**
* Now, when the designed attempts to write that to InitialiseComponent, it
queries DefaultValue; if it exists, it compares the values; if the
DefaultValue is different to the current property value, then an entry gets
written to the file.

Equally, I suspect this controls the bold / non-bold highlighting in the
designer.

Ironically and confusingly, what it does *NOT* do (in this case) is specify
the actual default value; this is defined by the field. The problem here is
that you have a different ctor value to DefaultValue; this is a recipe for
pain.

This is all necessary because it can't determine whether property "x" is
(for instance) date-driven (think .Now) {could be equally non-determinate in
any number of ways}.

Does that help?

Marc
 
T

tony

Hello!!

Only some questions on your post.
You say "You drag your shiny new control onto a form" it's ok no strange
about that
You say It runs the default ctor, which defaults (via the field default) to
false. It's ok no strange about that either.

But what do you mean here
Now, when the designed attempts to write that to InitialiseComponent, it
queries DefaultValue; if it exists, it compares the values; if the
DefaultValue is different to the current property value, then an entry gets
written to the file.

Can you make a very simple example about what you mean using this
DefaultValue?

//Tony
 
M

Marc Gravell

When all else fails, an example:

Code is below, but it consists of a custom control with 6 properties; there
are alternating true/false, but: the first two have no DefaultValue, the
second two have DefaultValue(true), and the last two have
DefaultValue(false).

Compile it, and drag it onto a form, and I get the following displayed in
the IDE (where * denotes bold - i.e. customised value):

Prop1 : *True*
Prop2 : *False*
Prop3 : True
Prop4 : *False*
Prop5 : *True*
Prop6 : False

This alternating patterm tells me immediately that the ctor has won over the
DefaultValue; so DefaultValue is not used when /creating/ objects (even via
the IDE). The relevent generated code is:

this.defaultedControl1.Prop1 = true;
this.defaultedControl1.Prop2 = false;
this.defaultedControl1.Prop4 = false;
this.defaultedControl1.Prop5 = true;

This is identical to the bold text as previous. Note that where the current
value on the control instance matches the value in DefaultValue (i.e. cases
3 and 6), then no code is generated. This also supports the "optimisation"
claim by another poster - less lines to trawl through.

Does that explain what I am saying? The moral is: if there is a sensible
(fixed) default for a property, then use DefaultValue; if a property isn't
predictable (i.e. it is itself an aggregate of 3 other fields, or depends on
the time, whatever), then you can't define a DefaultValue.

Note also that there are other attributes that control what appears in the
initialisation code - for instance DesignerSerializationVisibility (IIRC).

Marc

===================

using System;
using System.Windows.Forms;
using System.ComponentModel;

namespace Test {
class DefaultedControl : Control {
private bool _field1 = true, _field2 = false,
_field3 = true, _field4 = false,
_field5 = true, _field6 = false;

// no default; ctor true
public bool Prop1 {
get { return _field1; }
set { _field1 = value; }
}
// no default; ctor false
public bool Prop2 {
get { return _field2; }
set { _field2 = value; }
}
[DefaultValue(true)] // and ctor true
public bool Prop3 {
get { return _field3; }
set { _field3 = value; }
}
[DefaultValue(true)] // and ctor false
public bool Prop4 {
get { return _field4; }
set { _field4 = value; }
}
[DefaultValue(false)] // and ctor true
public bool Prop5 {
get { return _field5; }
set { _field5 = value; }
}
[DefaultValue(false)] // and ctor false
public bool Prop6 {
get { return _field6; }
set { _field6 = value; }
}
}
}
 
M

Marc Gravell

oh - and the other moral: the following is daft (the comment is correct,
though); don't do it... where DefaultValue is defined, it should ideally
match the ctor default value:

private int _field = 5;
[DefaultValue(17)] // WTF? should probably be 5
public int SomeProperty {
get {return _field;}
set {_field = value;}
}

You don't have to stick with the native defaults (false, 0, null), but where
you don't, keep them in sync. This is why I always declare my underlying
fields right next to the properties, so I can spot any goofs like the above.

Marc
 
N

Nick Hounsome

Better yet, tie them together using a private const.

private const int FieldDefault = 5;
private int _field = FieldDefault;
[DefaultValue(FieldDefault)]
 
T

tony

Hello!

I'm trying to copy your code and compile it and load it into the toolbox but
I run into problem.
I trying to understand this about [DefaultValue(false)]
This is what I do. You can correct me what I should do instead.

1. First I create a window application
2. I add a new project into the solution which is a Window Control Library.
3.I copy your code into the custom control file in the Window Control
Library'
4. I build this Window Control Library which is build into a dll
5. I add this Window Control Library dll into the toolbox.
6. I get the following error "There are no components in
....(WindowControlLibrary.dll that can
be placed on the toolbox.

When this failed I created a user control file in this Window Control
Library and copy your code
into the file and did the same build the Window Control Library into a dll
and tried to add to the toolbox
but got the same error message.


What should I do to test your code??


//Tony
 
M

Marc Gravell

OK, I don't know what is failing, but here's what I would do:

1: Create a new windows forms project.
2: Add a new *class* file; doesn't matter what you call it.
3: In the newly created file, replace the *entire* contents with the
contents from the previous post (from the ====== onwards)
4: Build
5: Go the the designer for Form1; in the toolbox, you should see
(automatically) local controls - such as DefaultedControl
6: Drag this onto the form; you won't see anything (except perhaps a ghosted
box), because there is no code there to draw anything...
7: Make sure that defaultedControl1 is selected (using the drop-down picker
if you can't find it visually), and look at the properties pane

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top