【发布时间】:2017-12-01 16:52:48
【问题描述】:
我正在尝试在 C# Forms 中构建一个自定义控件,让用户可以在控件上放置元素以直观地构建报表打印输出,但是我遇到了屏幕的一部分无法清除的问题,即使在绘制事件的顶部有明确的 e.Graphics.Clear 调用。
You can see here what happens when I maximize the window.
这是我的控件代码: 公共部分类 ReportBuilderControl : UserControl {
#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();
【问题讨论】:
-
您应该发布代码以支持您的问题和/或问题。请更新您的问题并在您遇到问题的地方发布代码
-
我建议调整大小后刷新窗口。
-
@HadiFooladiTalari 这行得通,但是当表单最大化时,剪辑矩形是全屏,我在整个剪辑矩形上尝试了 Graphics.Clear 和 Graphics.FillRectangle。当我应该在该区域上绘图时,为什么刷新表单会解决此问题?
-
@MethodMan 是的,在我将代码添加到问题中之前,我不小心在表单上按了 Enter,并立即对其进行了编辑。您的回复速度非常快!
-
好吧@Zalerinian 我是
Half man Half Amazing... LOL