Hi Golda
I want to write a custom renderer that allows me to dynamically change the width of the tab label. This is done based on the length of the text provided by an interface that the first child control in the tabpage implements (see code). The problem is, is that the tabcontrol does not recognize the resized tab sizes as calculated by GetCurrentBounds and simply uses the original sizes (based on the tab page text). For these reason cannot get the scroll bars to work at all.
Note, I do not want to just change the tab page text, but must do it with a renderer.
public class TabPageCountRenderer : TabRenderer2D
{
private TabControlAdv m_tabControlAdv = null;
private TabPageAdv m_tabPage = null;
private int m_localDeltaX = 0;
private int m_index = -1;
private int m_count = 0;
private int m_countPrevious = 0;
private Font m_fontInvalid = null;
private bool m_active = false;
private static TabPageCountPanelProperty tabPropertyExtender = null;
static TabPageCountRenderer()
{
tabPropertyExtender = new TabPageCountPanelProperty();
TabRendererFactory.RegisterTabType(TabStyleName, typeof(TabPageCountRenderer), new TabPageCountPanelProperty());
}
public static new TabPageCountPanelProperty TabPanelPropertyExtender
{
get { return tabPropertyExtender; }
}
public TabPageCountRenderer(ITabControl parent, ITabPanelRenderer panelRenderer)
: base(parent, panelRenderer)
{
m_tabControlAdv = parent.GetControl() as TabControlAdv;
if (m_tabControlAdv != null)
{
m_tabControlAdv.SelectedIndexChanged += new EventHandler(m_tabControlAdv_SelectedIndexChanged);
m_tabControlAdv.Disposed += new EventHandler(m_tabControlAdv_Disposed);
m_fontInvalid = new Font(m_tabControlAdv.Font, FontStyle.Bold);
}
}
public int Index
{
get { return m_index; }
}
public int GetDeltaX()
{
int deltaX = 0;
foreach(ITabRenderer renderer in m_tabControlAdv.Renderer.Renderers)
{
TabPageCountRenderer countRenderer = renderer as TabPageCountRenderer;
if(countRenderer != null)
{
if (countRenderer.Index < m_index)
{
deltaX += Rectangle.Round(countRenderer.GetCurrentBounds()).Width;
}
}
}
return deltaX;
}
public static new string TabStyleName
{
get { return "TabPageCountRenderer"; }
}
protected override void DrawText(Graphics g, RectangleF rectText, string text, StringFormat format, DrawTabEventArgs e)
{
if (m_active)
{
//Draw the tab text, depending on the selected state
if (m_tabControlAdv.SelectedIndex != m_index && m_countPrevious != m_count)
{
e.Font = m_fontInvalid;
}
else if (m_tabControlAdv.SelectedIndex == m_index)
{
e.Font = m_tabControlAdv.Font;
m_countPrevious = m_count;
}
rectText = RectangleF.FromLTRB(
rectText.Left - m_localDeltaX / 2,
rectText.Top,
rectText.Right + m_localDeltaX / 2,
rectText.Bottom);
text = string.Format("{0} ({1})", m_tabPage.Text, m_count);
}
base.DrawText(g, rectText, text, format, e);
}
void m_tabControlAdv_SelectedIndexChanged(object sender, EventArgs e)
{
if (m_tabControlAdv.SelectedIndex == m_index)
{
m_countPrevious = m_count;
}
}
public override RectangleF GetCurrentBounds()
{
RectangleF currentBounds = base.GetCurrentBounds();
int leftOffset = GetDeltaX();
currentBounds = RectangleF.FromLTRB(
leftOffset,
currentBounds.Top,
leftOffset + currentBounds.Width + m_localDeltaX,
currentBounds.Bottom);
return currentBounds;
}
public override ITabData TabData
{
get
{
return base.TabData;
}
set
{
//For a given renderer, the tabdata can be set multiple times
m_active = false;
base.TabData = value;
if (m_tabControlAdv != null && value != null)
{
foreach (TabPageAdv tabPage in m_tabControlAdv.TabPages)
{
if (tabPage.Text == value.Text)
{
m_tabPage = tabPage;
m_index = tabPage.TabIndex;
tabPage.TabIndexChanged -= new EventHandler(tabPage_TabIndexChanged);
tabPage.TabIndexChanged += new EventHandler(tabPage_TabIndexChanged);
if (tabPage.Controls.Count > 0 && tabPage.Controls[0] is ICountProvider)
{
((ICountProvider)tabPage.Controls[0]).CountChanged += new CountChangedHandler(TabPageCustomRenderer_CountChanged);
using (Graphics graphics = m_tabControlAdv.CreateGraphics())
{
m_localDeltaX = Size.Round(graphics.MeasureString("########", m_tabControlAdv.Font)).Width;
}
m_active = true;
}
break;
}
}
}
}
}
void m_tabControlAdv_Disposed(object sender, EventArgs e)
{
if (m_fontInvalid != null)
{
m_fontInvalid.Dispose();
}
}
void TabPageCustomRenderer_CountChanged(object sender, CountChangedEventArgs e)
{
m_count = e.Count;
Rectangle invalid = Rectangle.Round(base.GetRedrawBounds());
m_tabControlAdv.Invalidate(invalid, false);
}
void tabPage_TabIndexChanged(object sender, EventArgs e)
{
m_index = m_tabControlAdv.TabPages.IndexOf(m_tabPage);
}
}
>Hi Bert,
>
>I am afraid that I am not able to understand your requirement clearly. I have attached a sample that uses a custom renderer for TabControlAdv. Could you please modify the sample so that the issue could be seen clearly? Also please give me more information regarding this issue. This will help us to resolve the issue soon.
>
>We appreciate your interest in Syncfusion products.
>
>
http://websamples.syncfusion.com/samples/Tools.Windows/F61371/Main.htm>
>Best regards,
>Golda