2017-12-01 7 views
1

C#フォームでカスタムコントロールを作成しようとしていますが、ユーザーがコントロールに要素を配置してレポート印刷を視覚的に作成できるようになりましたが、ペイントイベントの先頭に明示的にe.Graphics.Clearコールがあっても、画面はクリアされません。ここでC#フォームで四角形がクリアされない

You can see here what happens when I maximize the window.

は、制御のための私のコードです: 公共部分クラスのReportBuilderControl:ユーザーコントロール{

#region Delegates 

    public delegate void SelectedElementChangedHandler(object sender, SelectedElementChangedEventArgs e); 

    #endregion Delegates 

    #region Events 

    public event SelectedElementChangedHandler SelectedElementChanged; 

    #endregion Events 

    #region Variables 

    private float mZoom = 1; 
    private PaperSize mPaperSize = new PaperSize("Paper", 850, 1100); 
    private List<PrintElement> mElements = new List<PrintElement>(); 
    private int mPageCount = 1; 


    #endregion Variables 

    public int PageCount { 
     get { return mPageCount; } 
     set { 
      mPageCount = value; 
      UpdateScrollbarSize(); 
     } 
    } 

    /// <summary> 
    /// The number of pixels each value of the scrollbar will move. Scaling does not affect this. 
    /// </summary> 
    public float ScrollSize { 
     get { return 10f; } 
    } 

    public int PagePadding { 
     get { return (int)(3 * ScrollSize * Zoom); } 
    } 

    public float Zoom { 
     get { return mZoom; } 
     set { 
      mZoom = value; 
      Invalidate(); 
      UpdateScrollbarSize(); 
     } 
    } 

    public int ScaledPageHeight { 
     get { 
      return (int)(mPaperSize.Height * Zoom); 
     } 
    } 

    private void UpdateScrollbarSize() { 
     VerticalScroll.Maximum = (int)Math.Ceiling(mPageCount * mPaperSize.Height/ScrollSize * Zoom + (PagePadding * (mPageCount + 1)/ScrollSize)); 
    } 

    public ReportBuilderControl() { 
     InitializeComponent(); 
     Paint += ReportBuilderControl_Paint; 
    } 

    private void ReportBuilderControl_Paint(object sender, PaintEventArgs e) { 
     // At the very least, we need to fill the clip rectangle with the background color. 
     e.Graphics.Clear(BackColor); 

     // Determine which pages are visible. 
     Rectangle vis = new Rectangle(0, 0, (int)(ClientRectangle.Width/Zoom), (int)(ClientRectangle.Height/Zoom)); 
     vis.Y = (int)(VerticalScroll.Value * ScrollSize); 
     int pageHeight = (int)(mPaperSize.Height * Zoom), 
      pageWidth = (int)(mPaperSize.Width * Zoom), 
      startPage = vis.Y/pageHeight, 
      endPage = (int)(Math.Ceiling(vis.Height/(double)pageHeight)) + startPage; 

     // Bring the invalidated rectangle to "Page Space", meaning an unzoomed, regular sized page, i.e. 850x1100 
     Rectangle clip = e.ClipRectangle; 
     clip.X = (int)(clip.X/Zoom); 
     clip.Y = (int)(clip.Y/Zoom); 
     clip.Width = (int)(clip.Width/Zoom); 
     clip.Height = (int)(clip.Height/Zoom); 

     // Draw visible pages, if the unzoomed page rectangle intersects the clip rectangle. 
     for (int i = startPage; i < endPage; ++i) { 
      // Calculate page rectangle. 
      int rectX = Math.Max((int)((ClientRectangle.Width - mPaperSize.Width) * 0.5), 0); 
      int rectY = PagePadding * (i + 1) + mPaperSize.Height * i; 
      Rectangle pageRect = new Rectangle(rectX, rectY, pageWidth, pageHeight); 
      if(pageRect.IntersectsWith(e.ClipRectangle)) { 
       Rectangle intersection = e.ClipRectangle; 
       intersection.Intersect(pageRect); 
       e.Graphics.FillRectangle(new SolidBrush(Color.WhiteSmoke), intersection); 
      } 
     } 
    } 
} 

そしてここでは、私のテストコードは、フォームを作成し、コントロールを添付することです:

 Form builder = new Form(); 
     ReportBuilderControl rpt = new ReportBuilderControl(); 
     rpt.BackColor = System.Drawing.Color.FromArgb(255, 14, 15, 15); 
     rpt.ClientSize = builder.ClientSize; 
     rpt.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Left; 
     builder.Controls.Add(rpt); 
     builder.ShowDialog(); 
+1

を..あなたの質問を更新し、あなたは私が提案する問題 – MethodMan

+1

を持っているコードを投稿してくださいサイズ変更後にウィンドウを更新します。 –

+0

@HadiFooladiTalariこれはうまくいきましたが、フォームが最大化されるとクリップ矩形がフルスクリーンになり、クリップ矩形全体でGraphics.ClearとGraphics.FillRectangleの両方を試しました。なぜ私はそのエリアを引き寄せようとしているときにフォームをリフレッシュするとこれを修正するのですか? – Zalerinian

答えて

0

サイズ変更後にウィンドウを更新します。ウィンドウを最大化すると、非表示の部分(すべてのウィンドウではない)だけが再描画されるためです。このコードは、このようなコンストラクタでResize += (s, e) => Refresh();入れ

:あなたはあなたの問題とや問題をサポートするためのコードをポストする必要があり

public ReportBuilderControl() 
{ 
    InitializeComponent(); 
    Paint += ReportBuilderControl_Paint; 
    Resize += (s, e) => Refresh(); 
} 
+3

' this.ResizeRedraw = true; 'をコンストラクタに追加するだけです。 Formクラスはコンテナコントロールとして扱われ、リサイズによって公開されるコントロールの部分だけを再描画する最適化が使用されます。 ResizeRedrawプロパティは、この最適化を抑制する簡単な方法です。 –

+0

なぜ、その理由が説明されます。お手伝いありがとう!私は、コントロール全体の再描画を避けることを望んでいましたが(最大化/復元を除いて)、リサイズされるたびにそれを行う必要がある場合は、C#フォームでは変更されていないと思います。再度、感謝します! – Zalerinian

関連する問題