By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,225 Members | 2,170 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,225 IT Pros & Developers. It's quick & easy.

Control doesn't repaint when using object with custom type converter

P: n/a
I've made a custom groupbox control. Inside, as one of it's members is
CSimpleGradient object. CSimpleGradient is a wrapper class for gradient
usage. Basically it looks like that:

[TypeConverter(typeof(CSimpleGradientConverter))]
public class CSimpleGradient
{
private float m_GradientAngle;
private Color m_ColorA;
private Color m_ColorB;

// Properties
blah blah ...

// Constructor
public CSimpleGradient(float _angle, Color _colorA, Color _colorB)
{
this.m_ColorA = _colorA;
this.m_ColorB = _colorB;
this.m_GradientAngle = _angle;
}
#endregion
}

It uses custom type converter(ExpandableObjectConverter). It's code goes
like this:
internal class CSimpleGradientConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type
sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
// Overrides the ConvertFrom method of TypeConverter.
public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value is string)
{
string[] v = ((string)value).Split(new char[] {','});
float angle = float.Parse(v[0]);
Color colorA = Color.FromName(v[1].Trim());
Color colorB = Color.FromName(v[2].Trim());
return new CSimpleGradient(angle, colorA, colorB);
}
return base.ConvertFrom(context, culture, value);
}
// Overrides the ConvertTo method of TypeConverter.
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo
culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((CSimpleGradient)value).Angle + "," +
((CSimpleGradient)value).ColorA + "," + ((CSimpleGradient)value).ColorB;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}

In my custom group-box class, CSimpleGradient properties looks like this:
[Category("Appearance_Header"), Description("Gets/Sets header gradient color
fill/gradient angle if HeaderFillType is set to Gradient."),
RefreshProperties(RefreshProperties.All),
DesignerSerializationVisibility(DesignerSerializat ionVisibility.Content)]
public CSimpleGradient HeaderGradientColor
{
get{return this.m_HeaderGradient;}
set
{
this.m_HeaderGradient = value;
this.Invalidate();
}
Everything works fine, but after changing values of CSimpleGradent object I
have to ALT+TAB forth and back to designer editor for changes to be
repainted.
I'm not sure why it doesn't work automatically since there is Invalidate
call in property's SET.

Please help! Thanks in advance!
D.
Nov 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Problem could be related to how Windows posts messages

As SDK help says

Calling the Invalidate method does not force a synchronous paint; to force a
synchronous paint, call the Update method after calling the Invalidate
method. When this method is called with no parameters, the entire client
area is added to the update region

Are you looking for synchronous paint?

HTH
Alex

"CroDude" <di***********@zg.htnet.hr> wrote in message
news:db**********@news1.xnet.hr...
I've made a custom groupbox control. Inside, as one of it's members is
CSimpleGradient object. CSimpleGradient is a wrapper class for gradient
usage. Basically it looks like that:

[TypeConverter(typeof(CSimpleGradientConverter))]
public class CSimpleGradient
{
private float m_GradientAngle;
private Color m_ColorA;
private Color m_ColorB;

// Properties
blah blah ...

// Constructor
public CSimpleGradient(float _angle, Color _colorA, Color _colorB)
{
this.m_ColorA = _colorA;
this.m_ColorB = _colorB;
this.m_GradientAngle = _angle;
}
#endregion
}

It uses custom type converter(ExpandableObjectConverter). It's code goes
like this:
internal class CSimpleGradientConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type
sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
// Overrides the ConvertFrom method of TypeConverter.
public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value is string)
{
string[] v = ((string)value).Split(new char[] {','});
float angle = float.Parse(v[0]);
Color colorA = Color.FromName(v[1].Trim());
Color colorB = Color.FromName(v[2].Trim());
return new CSimpleGradient(angle, colorA, colorB);
}
return base.ConvertFrom(context, culture, value);
}
// Overrides the ConvertTo method of TypeConverter.
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((CSimpleGradient)value).Angle + "," +
((CSimpleGradient)value).ColorA + "," + ((CSimpleGradient)value).ColorB;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}

In my custom group-box class, CSimpleGradient properties looks like this:
[Category("Appearance_Header"), Description("Gets/Sets header gradient color fill/gradient angle if HeaderFillType is set to Gradient."),
RefreshProperties(RefreshProperties.All),
DesignerSerializationVisibility(DesignerSerializat ionVisibility.Content)]
public CSimpleGradient HeaderGradientColor
{
get{return this.m_HeaderGradient;}
set
{
this.m_HeaderGradient = value;
this.Invalidate();
}
Everything works fine, but after changing values of CSimpleGradent object I have to ALT+TAB forth and back to designer editor for changes to be
repainted.
I'm not sure why it doesn't work automatically since there is Invalidate
call in property's SET.

Please help! Thanks in advance!
D.

Nov 17 '05 #2

P: n/a
Thanks Alex for help, but that didn't fix it.

I just want to repaint the control when HeaderGradientColor property changes
either from within DesignView or through the code.
It is so strange since all other properties are repainting correctly in
DesignView when using Invalidate in Set method.
All these(working) are standard types such as int, float, color etc. this
happens only with that custom one(CSimpleGradient).
Reallly strange!


Nov 17 '05 #3

P: n/a
Invalidate should post wm_paint. Update should call Paint.
You can try to find out what is going in with some profiler or just by
monitoring what you get in message loop.

"CroDude" <di***********@zg.htnet.hr> wrote in message
news:db**********@news1.xnet.hr...
Thanks Alex for help, but that didn't fix it.

I just want to repaint the control when HeaderGradientColor property changes either from within DesignView or through the code.
It is so strange since all other properties are repainting correctly in
DesignView when using Invalidate in Set method.
All these(working) are standard types such as int, float, color etc. this
happens only with that custom one(CSimpleGradient).
Reallly strange!

Nov 17 '05 #4

P: n/a
I found the solution ... You must invalidate through the designer object.
Here it goes:

public override void Initialize(IComponent component)
{
base.Initialize(component);
// Record instance of control we're designing
this.m_GroupBox = (CDizzyGroupBox) component;
// Hook up events
ISelectionService s = (ISelectionService)
GetService(typeof(ISelectionService));
IComponentChangeService c = (IComponentChangeService)
GetService(typeof(IComponentChangeService));
s.SelectionChanged += new EventHandler(OnSelectionChanged);
c.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving);
c.ComponentChanged+=new ComponentChangedEventHandler(OnComponentChanged);
}

private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
{
this.m_GroupBox.Update();
this.m_GroupBox.Invalidate();
}

protected override void Dispose(bool disposing)
{
ISelectionService s = (ISelectionService)
GetService(typeof(ISelectionService));
IComponentChangeService c = (IComponentChangeService)
GetService(typeof(IComponentChangeService));
// Unhook events
s.SelectionChanged -= new EventHandler(OnSelectionChanged);
c.ComponentRemoving -= new ComponentEventHandler(OnComponentRemoving);
c.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
base.Dispose(disposing);
}
Nov 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.