ItemCollections and custom UserControl...

T

Tinus

Hello all,
[I've been programming in C# for several months now, so bare with me... I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is painted
or resized. When the control is drawn it draws also the items found in the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in the
event I call the function that draws the control). Every time I add a item
to the collection I have to call the control.Refresh() function to update my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully someone in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
R

Ricky Lee

Hi Tinus,

First of all, if you're creating an owner-drawn custom calender (drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited if you
want to combine several basic/constituent controls into a single logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the Remove()
method of the Item object returned by the indexer. So you have to implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

Tinus said:
Hello all,
[I've been programming in C# for several months now, so bare with me... I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is painted
or resized. When the control is drawn it draws also the items found in the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in the
event I call the function that draws the control). Every time I add a item
to the collection I have to call the control.Refresh() function to update my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully someone in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
T

Tinus

Thanks Ricky!

Question 1 is now solved.... and it was so easy! But I really needed the
hint ;-)

As for question 2; How can I Invalidate() my control from either the Item
class of Items class? If I just make an instance to my control and then
Invalidate this instance then the results are: nothing happens. This is
because the instance does not have any items in it I think.

So can you once again give me one of your helpfull hints?

Also thanks for the flickerfree link... I'm going to look at it today.

Tinus

Ricky Lee said:
Hi Tinus,

First of all, if you're creating an owner-drawn custom calender (drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited if
you
want to combine several basic/constituent controls into a single logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with me... I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to update my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully someone
in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
T

Tinus

Ricky,

This 'flickerfree' link was awesome! No more flickering. Now the custom
control looks and feels really professional.

Thanks a lot!
Tinus

Ricky Lee said:
Hi Tinus,

First of all, if you're creating an owner-drawn custom calender (drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited if
you
want to combine several basic/constituent controls into a single logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with me... I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to update my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully someone
in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
R

Ricky Lee

Tinus,
Since you've solved question 1, I assume you now have a field in your Items
collection that points to the instance of your control owning this
collection. In the Items.Add method of your collection, call the
Invalidate() method of the owning control. For example:

public class Items : System.Collections.CollectionBase
{
// define field to point to owner control
// you can initialize it in the constructor
// or provide property accessor
private MyControl owner;

public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();
this.List.Add(item);
// invalidate the owning control
// to redraw with the new collection
if (owner != null)
owner.Invalidate();

return this;
}

Note: you have to provide a proper Paint logic for your control, to draw all
members of the Items collection.

Hope it helps.

-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
Tinus said:
Thanks Ricky!

Question 1 is now solved.... and it was so easy! But I really needed the
hint ;-)

As for question 2; How can I Invalidate() my control from either the Item
class of Items class? If I just make an instance to my control and then
Invalidate this instance then the results are: nothing happens. This is
because the instance does not have any items in it I think.

So can you once again give me one of your helpfull hints?

Also thanks for the flickerfree link... I'm going to look at it today.

Tinus

Ricky Lee said:
Hi Tinus,

First of all, if you're creating an owner-drawn custom calender (drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited if
you
want to combine several basic/constituent controls into a single logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with me... I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to
update
my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color)
function
but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully someone
in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
T

Tinus

Ehh, no....

I changed the public Item(name, number) function in the Item class to:

private Items _item;
public Item(Items items, string name, int number)
{
this._items = items;
...
}

and the public Items Add(string name, int number) to:

public Items Add(string name, int number)
{
this.Add(new Item(this, name, number));
return this;
}

The above code gives me the Items collection in the Item class. So now I
could add a Remove() function in the Item class:

public void Remove()
{
_items.Remove(this);
}

I think you had a different solution in mind? Can you give me an example of
how to do it your way?
How can I get an instance of my control in the Item class?

Many thanks!
Tinus

Ricky Lee said:
Tinus,
Since you've solved question 1, I assume you now have a field in your
Items
collection that points to the instance of your control owning this
collection. In the Items.Add method of your collection, call the
Invalidate() method of the owning control. For example:

public class Items : System.Collections.CollectionBase
{
// define field to point to owner control
// you can initialize it in the constructor
// or provide property accessor
private MyControl owner;

public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();
this.List.Add(item);
// invalidate the owning control
// to redraw with the new collection
if (owner != null)
owner.Invalidate();

return this;
}

Note: you have to provide a proper Paint logic for your control, to draw
all
members of the Items collection.

Hope it helps.

-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
message
Thanks Ricky!

Question 1 is now solved.... and it was so easy! But I really needed the
hint ;-)

As for question 2; How can I Invalidate() my control from either the Item
class of Items class? If I just make an instance to my control and then
Invalidate this instance then the results are: nothing happens. This is
because the instance does not have any items in it I think.

So can you once again give me one of your helpfull hints?

Also thanks for the flickerfree link... I'm going to look at it today.

Tinus

Ricky Lee said:
Hi Tinus,

First of all, if you're creating an owner-drawn custom calender
(drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited if
you
want to combine several basic/constituent controls into a single
logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection
and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with
me...
I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to update
my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function
but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully
someone
in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
R

Ricky Lee

Again I'll leave this one for your exercise. Hint: instead of using a
private field pointing to the Items collection, try using one pointing to
the owning control. Study the members of ListView, ListViewItemCollection,
and ListViewItem for ideas.

-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
Tinus said:
Ehh, no....

I changed the public Item(name, number) function in the Item class to:

private Items _item;
public Item(Items items, string name, int number)
{
this._items = items;
...
}

and the public Items Add(string name, int number) to:

public Items Add(string name, int number)
{
this.Add(new Item(this, name, number));
return this;
}

The above code gives me the Items collection in the Item class. So now I
could add a Remove() function in the Item class:

public void Remove()
{
_items.Remove(this);
}

I think you had a different solution in mind? Can you give me an example of
how to do it your way?
How can I get an instance of my control in the Item class?

Many thanks!
Tinus

Ricky Lee said:
Tinus,
Since you've solved question 1, I assume you now have a field in your
Items
collection that points to the instance of your control owning this
collection. In the Items.Add method of your collection, call the
Invalidate() method of the owning control. For example:

public class Items : System.Collections.CollectionBase
{
// define field to point to owner control
// you can initialize it in the constructor
// or provide property accessor
private MyControl owner;

public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();
this.List.Add(item);
// invalidate the owning control
// to redraw with the new collection
if (owner != null)
owner.Invalidate();

return this;
}

Note: you have to provide a proper Paint logic for your control, to draw
all
members of the Items collection.

Hope it helps.

-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
message
Thanks Ricky!

Question 1 is now solved.... and it was so easy! But I really needed the
hint ;-)

As for question 2; How can I Invalidate() my control from either the Item
class of Items class? If I just make an instance to my control and then
Invalidate this instance then the results are: nothing happens. This is
because the instance does not have any items in it I think.

So can you once again give me one of your helpfull hints?

Also thanks for the flickerfree link... I'm going to look at it today.

Tinus

Hi Tinus,

First of all, if you're creating an owner-drawn custom calender
(drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited if
you
want to combine several basic/constituent controls into a single
logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection
and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with
me...
I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of
you
can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized (in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to update
my
control with the added item. How can I make it so that whenever I
add
an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function
but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully
someone
in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
T

Tinus

Got it!

In my Items class I had to add:

private MyControl owner;
internal Datas(MyControl control)
{
this.owner = control;
}

And had to change Items items = new Items() in my custom control to:
Items items = new Items(this)

:) Now it works.

Ricky, thanks for your time and hints!

Tinus

Tinus said:
Ehh, no....

I changed the public Item(name, number) function in the Item class to:

private Items _item;
public Item(Items items, string name, int number)
{
this._items = items;
...
}

and the public Items Add(string name, int number) to:

public Items Add(string name, int number)
{
this.Add(new Item(this, name, number));
return this;
}

The above code gives me the Items collection in the Item class. So now I
could add a Remove() function in the Item class:

public void Remove()
{
_items.Remove(this);
}

I think you had a different solution in mind? Can you give me an example
of how to do it your way?
How can I get an instance of my control in the Item class?

Many thanks!
Tinus

Ricky Lee said:
Tinus,
Since you've solved question 1, I assume you now have a field in your
Items
collection that points to the instance of your control owning this
collection. In the Items.Add method of your collection, call the
Invalidate() method of the owning control. For example:

public class Items : System.Collections.CollectionBase
{
// define field to point to owner control
// you can initialize it in the constructor
// or provide property accessor
private MyControl owner;

public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();
this.List.Add(item);
// invalidate the owning control
// to redraw with the new collection
if (owner != null)
owner.Invalidate();

return this;
}

Note: you have to provide a proper Paint logic for your control, to draw
all
members of the Items collection.

Hope it helps.

-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
message
Thanks Ricky!

Question 1 is now solved.... and it was so easy! But I really needed the
hint ;-)

As for question 2; How can I Invalidate() my control from either the
Item
class of Items class? If I just make an instance to my control and then
Invalidate this instance then the results are: nothing happens. This is
because the instance does not have any items in it I think.

So can you once again give me one of your helpfull hints?

Also thanks for the flickerfree link... I'm going to look at it today.

Tinus

Hi Tinus,

First of all, if you're creating an owner-drawn custom calender
(drawing
using the graphics rectangle etc), it's better to derive your control from
the Control class instead of UserControl. UserControl is best suited
if
you
want to combine several basic/constituent controls into a single
logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the
Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the Remove(item)
method of the Items collection from the Remove() method of the Item class.
It's not hard to implement this. I'll leave the detail for your exercise.
Hint: you may need to define a private field in the Items collection
and
Item class to point to the their owner (i.e. an instance of your control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with
me...
I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found
in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a solution
for yet (googled for several days now :-( ). Hopefull someone of you can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized
(in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to update
my
control with the added item. How can I make it so that whenever I add an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw the
control. I've already tried to remove the Graphics.Clear(Color) function
but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully
someone
in
this newsgroup can tell me what to do with the first 2 questions.... they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 
R

Ricky Lee

Glad to help ;)


-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
Tinus said:
Got it!

In my Items class I had to add:

private MyControl owner;
internal Datas(MyControl control)
{
this.owner = control;
}

And had to change Items items = new Items() in my custom control to:
Items items = new Items(this)

:) Now it works.

Ricky, thanks for your time and hints!

Tinus

Ehh, no....

I changed the public Item(name, number) function in the Item class to:

private Items _item;
public Item(Items items, string name, int number)
{
this._items = items;
...
}

and the public Items Add(string name, int number) to:

public Items Add(string name, int number)
{
this.Add(new Item(this, name, number));
return this;
}

The above code gives me the Items collection in the Item class. So now I
could add a Remove() function in the Item class:

public void Remove()
{
_items.Remove(this);
}

I think you had a different solution in mind? Can you give me an example
of how to do it your way?
How can I get an instance of my control in the Item class?

Many thanks!
Tinus

Ricky Lee said:
Tinus,
Since you've solved question 1, I assume you now have a field in your
Items
collection that points to the instance of your control owning this
collection. In the Items.Add method of your collection, call the
Invalidate() method of the owning control. For example:

public class Items : System.Collections.CollectionBase
{
// define field to point to owner control
// you can initialize it in the constructor
// or provide property accessor
private MyControl owner;

public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();
this.List.Add(item);
// invalidate the owning control
// to redraw with the new collection
if (owner != null)
owner.Invalidate();

return this;
}

Note: you have to provide a proper Paint logic for your control, to draw
all
members of the Items collection.

Hope it helps.

-- Ricky Lee
==================================================
^o^ "When all doors are closed, God will open a Windows" ^o^
==================================================
message
Thanks Ricky!

Question 1 is now solved.... and it was so easy! But I really needed the
hint ;-)

As for question 2; How can I Invalidate() my control from either the
Item
class of Items class? If I just make an instance to my control and then
Invalidate this instance then the results are: nothing happens. This is
because the instance does not have any items in it I think.

So can you once again give me one of your helpfull hints?

Also thanks for the flickerfree link... I'm going to look at it today.

Tinus

Hi Tinus,

First of all, if you're creating an owner-drawn custom calender
(drawing
using the graphics rectangle etc), it's better to derive your control
from
the Control class instead of UserControl. UserControl is best suited
if
you
want to combine several basic/constituent controls into a single
logical
unit.

As to your questions:
1. The 'Items[1].Remove()' expression is basically calling the
Remove()
method of the Item object returned by the indexer. So you have to
implement
a Remove() method in your Item class. You can just call the
Remove(item)
method of the Items collection from the Remove() method of the Item
class.
It's not hard to implement this. I'll leave the detail for your
exercise.
Hint: you may need to define a private field in the Items collection
and
Item class to point to the their owner (i.e. an instance of your
control).

2. After adding the item to the collection, just call the Invalidate()
method of your control.

3. There are several techniques in reducing flicker. One of them is a
technique called 'Double Buffering'. You can just do some googling to
learn
more about double buffering. One site that you may find useful is
http://www.codeproject.com/cs/media/flickerFreeDrawing.asp.

Hope it helps. Good luck.

-- Ricky Lee
============================================
^o^ "When all doors are closed, God will open a Windows" ^o^
============================================

message
Hello all,
[I've been programming in C# for several months now, so bare with
me...
I'm
still a newbie]

I've create a custom control (UserControl) and have a custom Item
Collection. The control is a custom calendar which is draw using the
Graphics Rectangle etc. functions. It is drawn when the control is
painted
or resized. When the control is drawn it draws also the items found
in
the
collection.

So far so good.... I have 3 questions which I'm unable to find a
solution
for yet (googled for several days now :-( ). Hopefull someone of you
can
help me?

1. With a ListView control you can remove items using the
listView1.Items[1].Remove() or listView1.Remove(item). How does one
implement the first option (the second one I know how)?

2. The UserControl is drawn when the control is painted or resized
(in
the
event I call the function that draws the control). Every time I add a
item
to the collection I have to call the control.Refresh() function to
update
my
control with the added item. How can I make it so that whenever I add
an
item to my collection the control is (re)drawn automatically?

3. The drawn control flickers when I do a Refresh() or when I redraw
the
control. I've already tried to remove the Graphics.Clear(Color)
function
but
that did not help :-( How can I reduce the flickering?

Below I placed the item collection code (simplified). Hopefully
someone
in
this newsgroup can tell me what to do with the first 2 questions....
they
are really bugging me.

Thanks in advance!
Regards,
Tinus
(The Netherlands)
----
public class Items : System.Collections.CollectionBase
{
public virtual Items Add(Item item)
{
if (this.List.Contains(item))
throw new InvalidOperationException();

this.List.Add(item);

return this;
}

public virtual Items Add(string name, int number)
{
return this.Add(new Data(name, number));
}

public virtual Item this[int index]
{
get
{
if (index < 0 || index > this.List.Count)
throw new ArgumentOutOfRangeException();
return (Item)this.List[index];
}
}
}

public class Item
{
private string name;
private int number;

public string Name
{
get
{
return this.name;
}
}

public int Number
{
get
{
return this.number;
}
set
{
if (value < 0)
throw new ArgumentOutOfRangeException();
this.number = value;
}
}

public Item(string name, int number)
{
this.name = name;
this.number = number;
}
}
 

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