문제

예상대로 작동하지 않는 것을 제외하고는 이중 버퍼링을 가능하게하는 명시적인 목적으로 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)를 제거하면 작동해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top