파생 된 소유자가 그린 Tabcontrol의 이중 버퍼링 문제?
-
03-07-2019 - |
문제
예상대로 작동하지 않는 것을 제외하고는 이중 버퍼링을 가능하게하는 명시적인 목적으로 Tabcontrol을 도출했습니다. 다음은 TabControl 코드입니다.
class DoubleBufferedTabControl : TabControl
{
public DoubleBufferedTabControl() : base()
{
this.DoubleBuffered = true;
this.SetStyle
(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.SupportsTransparentBackColor,
false
);
}
}
그런 다음이 tabcontrol은 드로우 모드로 'jolderdrawnfixed'로 설정되어 색상을 변경할 수 있습니다. 사용자 정의 도면 방법은 다음과 같습니다.
private void Navigation_PageContent_DrawItem(object sender, DrawItemEventArgs e)
{
//Structure.
Graphics g = e.Graphics;
TabControl t = (TabControl)sender;
TabPage CurrentPage = t.TabPages[e.Index];
//Get the current tab
Rectangle CurrentTabRect = t.GetTabRect(e.Index);
//Get the last tab.
Rectangle LastTab = t.GetTabRect(t.TabPages.Count - 1);
//Main background rectangle.
Rectangle BackgroundRect = new Rectangle(LastTab.Width, t.Bounds.Y - 4, t.Width - (LastTab.Width), t.Height);
//Tab background rectangle.
Rectangle TabBackgroundRect = new Rectangle(0, LastTab.Y + LastTab.Height, LastTab.Width, t.Bounds.Height - (LastTab.Y + LastTab.Height));
//Set anitialiasing for the text.
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
//String format for the text.
StringFormat StringFormat = new StringFormat();
StringFormat.Alignment = StringAlignment.Center;
StringFormat.LineAlignment = StringAlignment.Center;
//Fill the background.
g.FillRectangle(Brushes.LightGray, BackgroundRect);
g.FillRectangle(Brushes.Bisque, TabBackgroundRect);
//Draw the selected tab.
if(e.State == DrawItemState.Selected)
{
g.FillRectangle(Brushes.White, e.Bounds);
Rectangle SelectedTabOutline = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width, e.Bounds.Height - 4);
g.DrawRectangle(new Pen(Brushes.LightGray, 4f), SelectedTabOutline);
g.DrawString(CurrentPage.Text, new Font("Arial", 12f, FontStyle.Bold, GraphicsUnit.Point), new SolidBrush(Color.FromArgb(70, 70, 70)), CurrentTabRect, StringFormat);
}
else
{
g.FillRectangle(new SolidBrush(Color.FromArgb(230, 230, 230)), e.Bounds);
g.DrawString(CurrentPage.Text, new Font("Arial", 12f, FontStyle.Regular, GraphicsUnit.Point), Brushes.Gray, CurrentTabRect, StringFormat);
}
}
그러나이 컨트롤은 이중 버퍼가 아니며 크기가 조정 될 때 여전히 플리커가 아니기 때문에 모두 소용이 없습니다.
어떤 아이디어?
해결책
문서를 읽으면 "이 회원은이 컨트롤에 의미가 없다"고 말합니다. 컨트롤을 이중 부러스를 사용하여 컨트롤을 그려 보려면 직접 구현해야합니다. 소유자를 제어 할 수있는 경우, 어쨌든 이중 소란을 구현해야한다는 사실 외에도.
다른 팁
우선, 당신은 당신의 TabControl
코드 - 버퍼링을 켜고 즉시 끄면 실제로 유용한 작업을 수행하지 않습니다.
문제의 일부는 당신이 그냥 페인트하려고한다는 것입니다. 부분 의 TabControl
.
약 90% 솔루션을 제공하는 가장 쉬운 솔루션 (여전히 깜박임을 할 수 있음)은 양식 클래스에 추가하는 것입니다.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
당신이되고 싶다면 매우 깜박임이 없다는 것은 전체를 그릴 필요가 있습니다. TabControl
자신과 배경 회화 요청을 무시하십시오.
편집 : 이것은 XP에서만 작동합니다.
나는 과거에 컨트롤에 대한 이중 버퍼링에 문제가 있었고 깜박임을 막는 유일한 방법은 상속 된 onpaintbackground 방법이 호출되지 않도록하는 것이 었습니다. (아래 코드 참조) 페인트 통화 중에 전체 백 그라운드가 페인트되어 있는지 확인해야합니다.
protected override void OnPaintBackground( PaintEventArgs pevent )
{
//do not call base - I don't want the background re-painted!
}
확실하지 않지만 탭 컨트롤이 포함 된 컨트롤을 이중 부러지는 시도를 시도 할 수 있습니다.
나는 주위를 약간 둘러 보았고, 당신의 코드와 내가 생각할 수있는 다른 것을 시도했지만, 깜박임을 제거 할 수있는 방법은 보이지 않습니다. 불행히도, 내 테스트에서는 크기 조정 중 규칙적인 (소유자가 아닌) 탭 컨트롤 플리커조차도 조화를 이룹니다.
가치가있는 것에 대해, "드래그하는 동안" "Show Window Contents"를 끄면 문제가 해결되지만 도움이되지 않을 수도 있습니다.
더블 버퍼링을 비활성화하고 있기 때문에 작동하지 않는다고 생각합니다!
모두 this.DoubleBuffered = true
does는 set controlstyles.optimizedDoubleBuffer to True입니다. 당신은 당신의 프로그램의 다음 줄에서 그 깃발을 비활성화하고 있기 때문에, 당신은 실제로 아무것도하지 않습니다. ControlStyles.OptimizedDoubleBuffer (및 아마도 ControlStyles.allPaintingInwmPaint)를 제거하면 작동해야합니다.