I would like to try out a code in Microsoft Visual C# Express Edition and I'm getting this error:
The type or namespace name 'Properties' does not exist in the namespace 'EducationalSuite.Core' (are you missing an assembly reference?)
I right click the Reference but I didn't find the "Properties" either the "EducationalSuite.Core".
Here is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Media;
using System.Resources;
namespace EducationalSuite.Core.Plugins
{
public delegate void RectangleItemClickedDelegate(Rectangle rect, int index);
public partial class GeoSafariItem : Control
{
protected List<Rectangle> lastFlashingItems = new List<Rectangle>();
protected int lastHeight = 0;
private Image imageFile = null;
protected List<Rectangle> hotspots = new List<Rectangle>();
protected Dictionary<int, string> textItems = new Dictionary<int, string>();
protected Dictionary<int, FileInfo> audioItems = new Dictionary<int, FileInfo>();
protected Rectangle lastRectangle;
protected int selectedIndex = 0;
protected int countItemsLeft = 6;
protected int countItemsRight = 6;
protected int imageOffsetTop = 0;
protected int imageOffsetBottom = 0;
protected bool paintHotSpots = false, colorSwitch = false, paintItemLabels = false;
protected Timer timer = new Timer();
public event RectangleItemClickedDelegate HotspotClick;
public event RectangleItemClickedDelegate QuestionItemClick;
public event RectangleItemClickedDelegate QuestionItemRightClick;
protected void OnHotspotClick(Rectangle rect, int index)
{
if (HotspotClick != null)
{
HotspotClick(this.RectangleToScreen(rect), index);
}
}
protected void OnQuestionItemRightClick(Rectangle rect, int index)
{
if (QuestionItemRightClick != null)
{
QuestionItemRightClick(this.RectangleToScreen(rect), index);
}
}
protected void OnQuestionItemClick(Rectangle rect, int index)
{
if (QuestionItemClick != null)
{
QuestionItemClick(this.RectangleToScreen(rect), index);
}
}
public GeoSafariItem()
{
this.imageFile = EducationalSuite.Core.Properties.Resources.singlepixel;
timer.Interval = 100;
timer.Tick += new EventHandler(timer_Tick);
timer.Enabled = true;
this.MouseUp += new MouseEventHandler(GeoSafariItem_MouseUp);
// Activates double buffering
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
this.DoubleBuffered = true;
//InitializeComponent();
}
public void SetItemText(int index, string text)
{
if (string.IsNullOrEmpty(text))
{
if (this.textItems.ContainsKey(index)) textItems.Remove(index);
}
else
{
this.textItems[index] = text;
}
if (PaintItemLabels)
{
this.Invalidate();
}
}
public string GetItemText(int index)
{
if (this.textItems.ContainsKey(index))
{
return this.textItems[index];
}
else
{
return string.Empty;
}
}
public void SetItemAudio(int index, FileInfo file)
{
if ((file == null) && !file.Exists)
{
if (this.audioItems.ContainsKey(index)) audioItems.Remove(index);
}
else
{
this.audioItems[index] = file;
}
}
public FileInfo GetItemAudio(int index)
{
if (this.audioItems.ContainsKey(index))
{
return this.audioItems[index];
}
else
{
return null;
}
}
#region Recording Regions
bool isRecording = false;
int recordingIndex = 0;
Point recordTopLeft = Point.Empty;
Point recordBottomRight = Point.Empty;
List<Rectangle> recordedRectangles = new List<Rectangle>();
public void StartRecording()
{
isRecording = true;
recordingIndex = 0;
selectedIndex = 0;
recordedRectangles.Clear();
this.MouseUp += new MouseEventHandler(GeoSafariItemRecord_MouseUp);
this.Invalidate();
}
public List<Rectangle> FinishRecording()
{
isRecording = false;
this.MouseUp -= new MouseEventHandler(GeoSafariItemRecord_MouseUp);
this.Invalidate();
this.Hotspots.Clear();
foreach (Rectangle r in recordedRectangles)
{
this.Hotspots.Add(r);
}
return recordedRectangles;
}
private void GeoSafariItemRecord_MouseUp(object sender, MouseEventArgs e)
{
if (isRecording)
{
Rectangle size = SizeRect;
double ratio = (double)imageFile.Height / (double)size.Height;
if (recordTopLeft == Point.Empty)
{
recordTopLeft = new Point(
(int)(((double)e.Location.X - (double)size.Left) * ratio),
(int)(((double)e.Location.Y - (double)size.Top) * ratio)
);
}
else
{
recordBottomRight = new Point(
(int)(((double)e.Location.X - (double)size.Left) * ratio),
(int)(((double)e.Location.Y - (double)size.Top) * ratio)
);
Rectangle r = new Rectangle(recordTopLeft,
new Size(recordBottomRight.X - recordTopLeft.X, recordBottomRight.Y - recordTopLeft.Y));
this.recordedRectangles.Add(r);
recordingIndex++;
selectedIndex++;
recordTopLeft = Point.Empty;
recordBottomRight = Point.Empty;
}
}
this.Invalidate();
}
#endregion
void timer_Tick(object sender, EventArgs e)
{
colorSwitch = !colorSwitch;
if (lastRectangle.Width > 0)
{
this.Invalidate(lastRectangle);
}
else
{
this.Invalidate();
}
}
private Rectangle SizeRect
{
get
{
int rw, rh,
cw = (this.Width - 42),
ch = (this.Height - 2),
ox = 21,
oy = 1;
rw = cw;
rh = ch;
double imageRatio = (double)imageFile.Width / (double)imageFile.Height;
double controlRatio = (double)cw / (double)ch;
if (controlRatio > imageRatio)
{
rw = (int)Math.Round((double)rh * imageRatio);
ox += Math.Abs(rw - cw) / 2;
}
else if (controlRatio < imageRatio)
{
rh = (int)Math.Round((double)rw / imageRatio);
oy += Math.Abs(rh - ch) / 2;
}
return new Rectangle(ox, oy, rw, rh);
}
}
void GeoSafariItem_MouseUp(object sender, MouseEventArgs e)
{
Rectangle size = SizeRect;
for (int i = 0; i < hotspots.Count; i++)
{
Rectangle hotspot = hotspots[i];
double ratio = (double)size.Height / (double)imageFile.Height;
Rectangle adjustedRectange = new Rectangle(
size.Left + (int)(hotspot.X * ratio),
size.Top + (int)(hotspot.Y * ratio),
(int)(hotspot.Width * ratio),
(int)(hotspot.Height * ratio));
if (adjustedRectange.Contains(e.Location))
{
OnHotspotClick(hotspot, i);
return;
}
}
for (int i = 0; i < lastFlashingItems.Count; i++)
{
if (lastFlashingItems[i].Contains(e.Location))
{
if (e.Button == MouseButtons.Right)
OnQuestionItemRightClick(lastFlashingItems[i], i);
else
OnQuestionItemClick(lastFlashingItems[i], i);
return;
}
}
}
public List<Rectangle> Hotspots
{
get { return hotspots; }
}
public Image ImageFile
{
get { return imageFile; }
set
{
imageFile = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int SelectedIndex
{
get { return selectedIndex; }
set { selectedIndex = value; this.Invalidate(); }
}
public int CountItemsLeft
{
get { return countItemsLeft; }
set
{
countItemsLeft = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int CountItemsRight
{
get { return countItemsRight; }
set
{
countItemsRight = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int ImageOffsetTop
{
get { return imageOffsetTop; }
set
{
imageOffsetTop = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int ImageOffsetBottom
{
get { return imageOffsetBottom; }
set
{
imageOffsetBottom = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public bool PaintHotSpots
{
get { return paintHotSpots; }
set { paintHotSpots = value; this.Invalidate(); }
}
public bool PaintItemLabels
{
get { return paintItemLabels; }
set { paintItemLabels = value; this.Invalidate(); }
}
protected override void OnPaint(PaintEventArgs pe)
{
Graphics g = pe.Graphics;
string itemText;
SizeF sizeItemText;
double topOffset = imageOffsetTop;
double bottomOffset = imageOffsetBottom;
double topOffsetPct = (double)topOffset / (double)imageFile.Height;
double bottomOffsetPct = (double)bottomOffset / (double)imageFile.Height;
Rectangle size = SizeRect;
SolidBrush brush = new SolidBrush(this.BackColor);
g.FillRectangle(brush, 0, 0, this.Width - 1, this.Height - 1);
g.FillRectangle(Brushes.Ivory, size.X - 25, size.Y, size.Width + 50, size.Height);
g.DrawRectangle(Pens.DarkKhaki, size.X - 25, size.Y - 1, size.Width + 50, size.Height + 1);
g.DrawImage(imageFile, size.X, size.Y, size.Width, size.Height);
Rectangle rect, rectItemText;
Brush selectedColor = (colorSwitch ? Brushes.Crimson : Brushes.Red);
topOffset = topOffsetPct * size.Height;
bottomOffset = bottomOffsetPct * size.Height;
int tmpHeight = (size.Height - (int)topOffset - (int)bottomOffset) / countItemsLeft;
if (size.Height != this.lastHeight || this.lastFlashingItems.Count == 0)
{
lastHeight = size.Height;
lastFlashingItems.Clear();
int actualIndex = 0;
for (int i = 0; i < countItemsLeft; i++)
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
int xx = size.X - 18;
rect = new Rectangle(xx, yy, 16, 8);
this.lastFlashingItems.Add(rect);
g.FillRectangle((actualIndex == selectedIndex ? selectedColor : Brushes.Khaki), rect);
g.DrawRectangle(Pens.DarkKhaki, rect);
if (actualIndex == selectedIndex)
{
lastRectangle = rect;
}
itemText = this.GetItemText(actualIndex);
if (PaintItemLabels && !string.IsNullOrEmpty(itemText))
{
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + 10;
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
tmpHeight = (size.Height - (int)topOffset - (int)bottomOffset) / countItemsRight;
for (int i = 0; i < countItemsRight; i++)
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
int xx = size.X + size.Width + 2;
rect = new Rectangle(xx, yy, 16, 8);
this.lastFlashingItems.Add(rect);
g.FillRectangle((actualIndex == selectedIndex ? selectedColor : Brushes.Khaki), rect);
g.DrawRectangle(Pens.DarkKhaki, rect);
if (actualIndex == selectedIndex)
{
lastRectangle = rect;
}
itemText = this.GetItemText(actualIndex);
if (PaintItemLabels && !string.IsNullOrEmpty(itemText))
{
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + size.Width - 10 - Convert.ToInt32(sizeItemText.Width);
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
}
else
{
lastHeight = size.Height;
for (int i = 0; i < lastFlashingItems.Count; i++)
{
g.FillRectangle((i == selectedIndex ? selectedColor : Brushes.Khaki), lastFlashingItems[i]);
g.DrawRectangle(Pens.DarkKhaki, lastFlashingItems[i]);
if (i == selectedIndex)
{
lastRectangle = lastFlashingItems[i];
}
}
if (PaintItemLabels)
{
int actualIndex = 0;
for (int i = 0; i < countItemsLeft; i++)
{
itemText = this.GetItemText(actualIndex);
if (!string.IsNullOrEmpty(itemText))
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + 10;
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
tmpHeight = (size.Height - (int)topOffset - (int)bottomOffset) / countItemsRight;
for (int i = 0; i < countItemsRight; i++)
{
itemText = this.GetItemText(actualIndex);
if (!string.IsNullOrEmpty(itemText))
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + size.Width - 10 - Convert.ToInt32(sizeItemText.Width);
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
}
}
// Calling the base class OnPaint
base.OnPaint(pe);
if (this.isRecording)
{
for (int i = 0; i < this.recordedRectangles.Count; i++)
{
rect = recordedRectangles[i];
double ratio = (double)size.Height / (double)imageFile.Height;
Rectangle adjustedRectange = new Rectangle(
size.Left + (int)(rect.X * ratio),
size.Top + (int)(rect.Y * ratio),
(int)(rect.Width * ratio),
(int)(rect.Height * ratio));
PaintHotspot(g, Color.LightBlue, adjustedRectange, (i + 1).ToString());
}
}
else if (this.paintHotSpots)
{
for (int i = 0; i < hotspots.Count; i++)
{
Rectangle hotspot = hotspots[i];
double ratio = (double)size.Height / (double)imageFile.Height;
Rectangle adjustedRectange = new Rectangle(
size.Left + (int)(hotspot.X * ratio),
size.Top + (int)(hotspot.Y * ratio),
(int)(hotspot.Width * ratio),
(int)(hotspot.Height * ratio));
PaintHotspot(g, Color.LightGreen, adjustedRectange, (i + 1).ToString());
}
}
}
protected virtual void PaintHotspot(Graphics g, Color c, Rectangle hotspot, int alpha)
{
PaintHotspot(g, c, hotspot, alpha, null);
}
protected virtual void PaintHotspot(Graphics g, Color c, Rectangle hotspot, string txt)
{
PaintHotspot(g, c, hotspot, 100, txt);
}
protected virtual void PaintHotspot(Graphics g, Color c, Rectangle hotspot, int alpha, string txt)
{
SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, c));
g.FillRectangle(brush, hotspot);
if (!string.IsNullOrEmpty(txt))
g.DrawString(txt, this.Font, Brushes.DarkGreen, hotspot.Location);
}
}
}
Update
I imagine the following line is causing the error.
this.imageFile = EducationalSuite.Core.Properties.Resources.singlepixel;
The code is referring to a image resource "singlepixel". This image must be in the default resource file of the EducationalSuite.Core assembly. First confirm that you are currently editing the said assembly by opening Project Properties and checking the Default Namespace on the Application page. This should state "EducationalSuite.Core". If this isn't the case, you are most likely missing a reference to the said assembly.
If you have the EducationalSuite.Core project open the easiest way to add the singlepixel resource is to open project properties, Resources tab and creating a new default resource file. From the top open the Add Resource drop down and select existing file or new image depending on whether you have the file already or if you need to create it. Name the resource "singlepixel".
Visual Studio will generate Resources helper class under Properties namespace for you so you can access the resource through the Properties.Resources.singlepixel under EducationalSuite.Core in your code.
Old answer
In general Properties namespace is the namespace which contains application or user specific settings. You can add these settings (and the namespace) by navigating to the Settings tab in the Properties of the project.
Unfortunately it's kind of hard to say more based on this information. Could you provide the piece of code that causes this error?
If you double click the error message the IDE will take you to the line which is causing the error.
Most likely the piece of code is expecting a setting variable which is not added to the project.
Looks like you are missing the Reference. If it is not under References in solution explorer than I would do a file search in windows for "EducationalSuite.Core" to see where it is on the system and add it. You may also be missing the "using" statement? If you hover over the "Properties" text you should get a small drop down that will add the using's for you.
If this does not help, more information would be helpful?
Hope this helps!
Related
I'm Fairly new to WPF and MVVM in general, I'm trying to follow this tutorial to create a stacked bar chart in telerik/WPF C#:
https://docs.telerik.com/devtools/winforms/knowledge-base/chartview-summary-labels-stacked-bars
But I'm, unsure where to implement the "Custom Renderer and Labels" Code, Can't seem to have it work. Should I declare a seperate class or something? A rough step by step guide is all i need, thanks in advance
this is the example code (I'm not sure where to put it)
public class CustomCartesianRenderer : CartesianRenderer
{
public CustomCartesianRenderer(CartesianArea area)
: base(area)
{ }
protected override void InitializeSeriesLabels()
{
base.InitializeSeriesLabels();
IDictionary<object, List<double?>> summaryValues = new Dictionary<object, List<double?>>();
for (int i = 0; i < this.Area.Series.Count; i++)
{
BarSeries barSeries = this.Area.Series[i] as BarSeries;
if (barSeries == null)
{
continue;
}
for (int j = 0; j < barSeries.DataPoints.Count; j++)
{
CategoricalDataPoint dp = (CategoricalDataPoint)barSeries.DataPoints[j];
if (!summaryValues.ContainsKey(dp.Category))
{
summaryValues.Add(dp.Category, new List<double?>() { dp.Value });
}
else
{
summaryValues[dp.Category].Add(dp.Value);
}
}
}
string lastSeriesName = this.Area.Series[this.Area.Series.Count - 1].Name;
for (int i = 0; i < this.DrawParts.Count; i++)
{
BarLabelElementDrawPart labelPart = this.DrawParts[i] as BarLabelElementDrawPart;
if (labelPart != null && labelPart.Element.Name == lastSeriesName)
{
CustomBarLabelElementDrawPart customLabelPart = new CustomBarLabelElementDrawPart((BarSeries)labelPart.Element, this);
customLabelPart.SummaryValues = summaryValues;
this.DrawParts[i] = customLabelPart;
}
}
}
}
public class CustomBarLabelElementDrawPart : BarLabelElementDrawPart
{
private IDictionary<object, List<double?>> summaryValues;
public CustomBarLabelElementDrawPart(BarSeries series, IChartRenderer renderer)
: base(series, renderer)
{ }
public IDictionary<object, List<double?>> SummaryValues
{
get
{
return this.summaryValues;
}
set
{
this.summaryValues = value;
}
}
public override void Draw()
{
Graphics graphics = this.Renderer.Surface as Graphics;
RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
foreach (DataPointElement dataPointElement in this.Element.Children)
{
CategoricalDataPoint categoricalDataPoint = dataPointElement.DataPoint as CategoricalDataPoint;
if (!this.summaryValues.ContainsKey(categoricalDataPoint.Category))
{
continue;
}
double? sum = this.summaryValues[categoricalDataPoint.Category].Sum();
string summaryText = string.Format("Sum: {0}", sum);
RadRect slot = categoricalDataPoint.LayoutSlot;
RectangleF barBounds = new RectangleF((float)(this.OffsetX + slot.X), (float)(this.OffsetY + slot.Y), (float)slot.Width, (float)slot.Height);
float realHeight = barBounds.Height * dataPointElement.HeightAspectRatio;
barBounds.Y += barBounds.Height - realHeight;
barBounds.Height = realHeight;
barBounds = this.AdjustBarDataPointBounds(dataPointElement, barBounds);
barBounds.Width = Math.Max(barBounds.Width, 1f);
object state = radGraphics.SaveState();
int horizontalTranslate = (int)(barBounds.X + barBounds.Width / 2);
int verticalTranslate = (int)(barBounds.Y + barBounds.Height / 2);
float angle = (float)this.Element.LabelRotationAngle % 360f;
if (angle != 0)
{
radGraphics.TranslateTransform(horizontalTranslate, verticalTranslate);
radGraphics.RotateTransform(angle);
radGraphics.TranslateTransform(-horizontalTranslate, -verticalTranslate);
}
Size desiredSize = TextRenderer.MeasureText(summaryText, dataPointElement.Font);
FillPrimitiveImpl fill = new FillPrimitiveImpl(dataPointElement, null);
fill.PaintFill(radGraphics, 0, Size.Empty, barBounds);
BorderPrimitiveImpl border = new BorderPrimitiveImpl(dataPointElement, null);
border.PaintBorder(radGraphics, 0, Size.Empty, barBounds);
using (Brush brush = new SolidBrush(dataPointElement.ForeColor))
{
RectangleF drawRectangle = new RectangleF();
drawRectangle.X = barBounds.X + dataPointElement.Padding.Left + (barBounds.Width - desiredSize.Width) /2;
drawRectangle.Y = barBounds.Y + dataPointElement.Padding.Top - desiredSize.Height;
drawRectangle.Width = barBounds.Width - dataPointElement.Padding.Right;
drawRectangle.Height = barBounds.Height - dataPointElement.Padding.Bottom;
StringFormat format = new StringFormat();
graphics.DrawString(summaryText, dataPointElement.Font, brush, drawRectangle, format);
}
if (angle != 0)
{
radGraphics.ResetTransform();
}
radGraphics.RestoreState(state);
}
base.Draw();
}
private RectangleF AdjustBarDataPointBounds(DataPointElement point, RectangleF bounds)
{
RectangleF barBounds = bounds;
if (point.BorderBoxStyle == BorderBoxStyle.SingleBorder || point.BorderBoxStyle == BorderBoxStyle.OuterInnerBorders)
{
barBounds.X += point.BorderWidth - (int)((point.BorderWidth - 1f) / 2f);
barBounds.Width -= point.BorderWidth;
barBounds.Y += point.BorderWidth - (int)((point.BorderWidth - 1f) / 2f);
barBounds.Height -= point.BorderWidth;
}
else if (point.BorderBoxStyle == BorderBoxStyle.FourBorders)
{
barBounds.Y += 1;
barBounds.Height -= 1;
barBounds.X += 1;
barBounds.Width -= 1;
}
if (((CartesianRenderer)this.Renderer).Area.Orientation == System.Windows.Forms.Orientation.Horizontal)
{
barBounds.X--;
}
return barBounds;
}
}
I am making a software to help me at work. It reads two excel (xlsx) files and get some info from them. Then it put the info in one of the two datagridviews or in both datagridviews.
Then i have a number that i need to show when i print the datagridviews. In print preview all is exactly as i want but when printing on paper it removes (or doesn't remember) everything about first datagridview and anything i print with it and start from the 2nd datagridview.
Here how it shows in print preview:
but when i print it on paper i get like this
Why the first datagridview gone on paper but if i print it PDF from Microsoft print to PDF i get PDF that has exactly as the preview.
Problem only when printing on paper.
Here is my printing code https://pastebin.com/6ZF2FevZ
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Drawing.Text;
using System.Linq;
using System.Windows.Forms;
namespace Motabaka
{
class DGVsPrinter
{
private Font fontD;
private Brush brushD = Brushes.Black;
private bool dgv1Finished;
private string a3800, a1800;
public string Title { get; set; }
public bool IncludeDateAndTimeInFooter { get; set; }
public bool IncludePageNumberInFooter { get; set; }
public bool IncludeEndingPhraseAtTheEnd { get; set; }
public string EndingPhrase { get; set; } = "End";
private DataGridView dataGridView1, dataGridView2;
private int rowIndex;
private int cellCount;
private int pageNumber = 1;
private readonly PrintDocument printDoc;
private int iTotalWidth1;
private int iTotalWidth2;
private Dictionary<int, int> ColumntWidths;
private Dictionary<int, int> arrColumnWidths1 = new Dictionary<int, int>();
private Dictionary<int, int> arrColumnWidths2 = new Dictionary<int, int>();
private bool preview;
public DGVsPrinter(DataGridView dataGridView1, DataGridView dataGridView2, PrintDocument printDoc, string A3800, string A1800)
{
this.dataGridView1 = dataGridView1;
this.dataGridView2 = dataGridView2;
this.printDoc = printDoc;
fontD = new Font(dataGridView1.Font, FontStyle.Bold);
printDoc.BeginPrint += OnBeginPrint;
printDoc.PrintPage += OnPrintPage;
a3800 = A3800;
a1800 = A1800;
}
public void Print(bool preview = false)
{
this.preview = preview;
rowIndex = 0;
cellCount = 0;
pageNumber = 0;
var dgvs = new DataGridView[] { dataGridView1, dataGridView2 };
foreach (DataGridView dgv in dgvs)
{
var rows = dgv.Rows
.Cast<DataGridViewRow>()
.FirstOrDefault(r => !r.IsNewRow && r.Visible);
if (rows != null)
cellCount = rows.Cells
.Cast<DataGridViewCell>()
.Where(c => c.Visible)
.Count();
if (cellCount == 0)
{
//MessageBox.Show(new Form() { FormBorderStyle = FormBorderStyle.None }, "Nothing to print...");
continue;
}
}
if (cellCount == 0)
{
MessageBox.Show(new Form() { FormBorderStyle = FormBorderStyle.None }, "Nothing to print...");
return;
}
if (preview)
{
try
{
using (var pd = new PrintPreviewDialog())
{
pd.Document = printDoc;
pd.ShowDialog();
}
}
catch (Exception ex)
{
Error.Log(ex);
}
}
else
{
try
{
using (var pd = new PrintDialog())
{
pd.Document = printDoc;
if (pd.ShowDialog() == DialogResult.OK)
{
pd.Document.Print();
}
}
}
catch (Exception ex)
{
Error.Log(ex);
}
}
}
private void OnBeginPrint(object sender, PrintEventArgs e)
{
try
{
rowIndex = 0; pageNumber = 1;
iTotalWidth1 = 0;
iTotalWidth2 = 0;
arrColumnWidths1.Clear();
arrColumnWidths2.Clear();
foreach (DataGridViewColumn dgvGridCol in dataGridView1.Columns)
{
if (!dgvGridCol.Visible) { continue; }
iTotalWidth1 += dgvGridCol.Width;
}
foreach (DataGridViewColumn dgvGridCol in dataGridView2.Columns)
{
if (!dgvGridCol.Visible) { continue; }
iTotalWidth2 += dgvGridCol.Width;
}
}
catch (Exception ex)
{
Error.Log(ex, "Error while printing [OnBeginPrint]");
}
}
private void OnPrintPage(object sender, PrintPageEventArgs e)
{
try
{
e.Graphics.Clear(Color.White);
var w = e.MarginBounds.Width / cellCount;
var x = e.MarginBounds.X;
var y = e.MarginBounds.Y;
int h;
Rectangle rec;
while (true)
{
var dgv = !dgv1Finished ? dataGridView1 : dataGridView2;
ColumntWidths = (dgv == dataGridView1) ? arrColumnWidths1 : arrColumnWidths2;
var totalWidths = (dgv == dataGridView1) ? iTotalWidth1 : iTotalWidth2;
var iTmpWidth = 0;
if (pageNumber == 1)
{
for (int i = dgv.Columns.Count - 1; i >= 0; i--)
{
DataGridViewColumn GridCol = dgv.Columns[i];
if (!GridCol.Visible) continue;
iTmpWidth = (int)(Math.Floor(GridCol.Width /
(double)totalWidths * totalWidths *
(e.MarginBounds.Width / (double)totalWidths)));
if (!ColumntWidths.Keys.Contains(GridCol.Index))
{
ColumntWidths.Add(GridCol.Index, iTmpWidth);
}
}
}
using (var sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
sf.Trimming = StringTrimming.None;
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
// Uncomment to print the headers in the first page only.
//if (pageNumber == 1)
//{
h = dgv.RowTemplate.Height + 20;
#region Title
var TextToDraw = dgv.Tag?.ToString();
var xCenter = e.MarginBounds.Left + e.MarginBounds.Width / 2;
e.Graphics.DrawString(TextToDraw, fontD, brushD, xCenter, y - 20, sf);
#endregion
using (var strf = new StringFormat())
{
strf.Alignment = StringAlignment.Far;
strf.LineAlignment = StringAlignment.Near;
#region Amount
var amount = (dgv == dataGridView1) ? a1800 : a3800;
var XC = e.MarginBounds.Right;
var font = new Font(dgv.Font.FontFamily, 12f, FontStyle.Regular);
e.Graphics.DrawString(amount, font, brushD, XC, y - 20, strf);
#endregion
}
for (int i = dgv.Columns.Count - 1; i >= 0; i--)
{
var col = dgv.Columns[i];
if (col.Visible)
{
w = ColumntWidths[col.Index];
rec = new Rectangle(x, y, w, h);
e.Graphics.FillRectangle(Brushes.AliceBlue, rec);
e.Graphics.DrawString(
col.HeaderText,
col.DataGridView.Font,
Brushes.Black,
rec,
sf);
//Pen pen = new Pen(Color.Black, 1.3f);
//pen.Alignment = PenAlignment.Inset;
//e.Graphics.DrawRectangle(pen, rec);
Color[] colors;
if (false)
{
colors = new Color[]
{
SystemColors.ControlDark,
SystemColors.ControlDarkDark,
SystemColors.ControlLightLight,
SystemColors.ControlLight
};
}
else
{
colors = new Color[]
{
SystemColors.ControlLightLight,
SystemColors.ControlLight,
SystemColors.ControlDark,
SystemColors.ControlDarkDark
};
}
using (Pen p = new Pen(colors[0]))
{
e.Graphics.DrawLine(p, rec.X, rec.Bottom - 1,
rec.X, rec.Y);
e.Graphics.DrawLine(p, rec.X, rec.Y,
rec.Right - 1, rec.Y);
}
using (Pen p = new Pen(colors[1]))
{
e.Graphics.DrawLine(p, rec.X + 1, rec.Bottom - 2,
rec.X + 1, rec.Y + 1);
e.Graphics.DrawLine(p, rec.X + 1, rec.Y + 1,
rec.Right - 2, rec.Y + 1);
}
using (Pen p = new Pen(colors[2]))
{
e.Graphics.DrawLine(p, rec.X, rec.Bottom - 1,
rec.Right - 1, rec.Bottom - 1);
e.Graphics.DrawLine(p, rec.Right - 1, rec.Bottom - 1,
rec.Right - 1, rec.Y);
}
using (Pen p = new Pen(colors[3]))
{
e.Graphics.DrawLine(p, rec.X + 1, rec.Bottom - 2,
rec.Right - 2, rec.Bottom - 2);
e.Graphics.DrawLine(p, rec.Right - 2, rec.Bottom - 2,
rec.Right - 2, rec.Y + 1);
}
x += w;
}
}
x = e.MarginBounds.X;
y += h;
//}
/*Drawing the rows with their content*/
for (var i = rowIndex; i < dgv.RowCount; i++)
{
var row = dgv.Rows[i];
if (!row.Visible) continue;
if (row.IsNewRow) break;
h = GetRowHeight(e.Graphics, row, e.MarginBounds, sf);
if (h > e.MarginBounds.Height)
{
MessageBox.Show("Insufficient height.");
e.Cancel = true;
return;
}
/*Drawing row's cells with their content*/
for (int r = row.Cells.Count - 1; r >= 0; r--)
{
var cell = row.Cells[r];
if (!cell.Visible) { continue; }
w = ColumntWidths[cell.ColumnIndex];
rec = new Rectangle(x, y, w, h);
if (rec.Bottom > e.MarginBounds.Bottom)
{
pageNumber++;
rowIndex = i;
e.HasMorePages = true;
return;
}
var color = (cell.InheritedStyle.BackColor == Color.Yellow) ? new SolidBrush(SystemColors.Window) : new SolidBrush(cell.InheritedStyle.BackColor);
e.Graphics.FillRectangle(color, rec);
e.Graphics.DrawString(
cell.FormattedValue.ToString(),
dgv.Font,
Brushes.Black,
rec,
sf);
e.Graphics.DrawRectangle(Pens.Black, rec);
x += rec.Width;
}/*Done drawing the cells in a row*/
x = e.MarginBounds.X;
y += h;
}/*Done drawing all the rows*/
#region Date and time
if (IncludeDateAndTimeInFooter)
{
var strDate = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString();
var wdate = e.Graphics.MeasureString(strDate, fontD, e.MarginBounds.Height, sf).Width;
var hdate = e.Graphics.MeasureString(strDate, fontD, e.MarginBounds.Height, sf).Height;
var yBottom = e.MarginBounds.Height + e.MarginBounds.Top;
var recDate = new Rectangle(e.MarginBounds.X, yBottom, e.MarginBounds.Width, (int)hdate);
//e.Graphics.FillRectangle(Brushes.LightSkyBlue, recDate);
e.Graphics.DrawRectangle(Pens.Black, recDate);
e.Graphics.DrawString(strDate, fontD, brushD, recDate.X, yBottom);
}
#endregion
#region Page Number
if (IncludePageNumberInFooter)
{
var pNumber = "Page " + pageNumber;
var yBottom = e.MarginBounds.Height + e.MarginBounds.Top;
var xRight = e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(pNumber, fontD, e.MarginBounds.Width, sf).Width);
e.Graphics.DrawString(pNumber, fontD, brushD, xRight, yBottom);
}
#endregion
y = y + 70;
rowIndex = 0;
dgv1Finished = true;
e.HasMorePages = (dgv == dataGridView1);
}
if (!e.HasMorePages)
{
if (IncludeEndingPhraseAtTheEnd)
{
using (var strf = new StringFormat())
{
strf.LineAlignment = StringAlignment.Center;
strf.Alignment = StringAlignment.Center;
strf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
var fontD = new Font(dgv.Font, FontStyle.Bold);
var brushD = Brushes.Black;
var xCenter = e.MarginBounds.Left + e.MarginBounds.Width / 2;
var yBottom = e.MarginBounds.Top
+ e.MarginBounds.Height
+ e.Graphics.MeasureString(EndingPhrase, fontD, e.MarginBounds.Height, strf).Height;
e.Graphics.DrawString(EndingPhrase, fontD, brushD, xCenter, y - 60, strf);
}
}
break;
}
}
}
catch (Exception ex)
{
Error.Log(ex, " Error while printing [OnPrintPage]");
}
}
private int GetRowHeight(
Graphics g,
DataGridViewRow row,
Rectangle bounds,
StringFormat sf,
int minHeight = 22)
{
var cells = row.Cells.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible);
if (cells == null) return minHeight;
/*(longest, next) => next.Length > longest.Length ? next : longest*/
var cell = cells.Aggregate((DataGridViewTextBoxCell)null, (x, y) => (x != null) && (!string.IsNullOrWhiteSpace(x.FormattedValue.ToString()) && !string.IsNullOrWhiteSpace(y.FormattedValue.ToString())) &&
(x.FormattedValue.ToString().Length > y.FormattedValue.ToString().Length) ? x : y);
if (cell == null) return minHeight;
var h = g.MeasureString(cell.FormattedValue.ToString(),
row.DataGridView.Font,
new SizeF(ColumntWidths[cell.ColumnIndex], bounds.Height),
sf).ToSize().Height;
return Math.Max(h + 10, minHeight); // 6 for top and bottom margins...
}
}
}
I call the print like this
var print = new DGVsPrinter(dataGridView1, dataGridView2, printDocument1, Final3800L.Text, Final1800L.Text)
{
IncludeDateAndTimeInFooter = true,
IncludePageNumberInFooter = true
};
print.Print(true);
I found the problem.
If i print it by print dialog it prints good. But when i show the preview, this problem happens. Because i didn't set dgv1Finished to false on OnBeginPrint.
when it actually prints It runs the code again and dgv1Finished is already true after the preview so it get datagridview2 first and nothing about datagridvie1.
I only have to set dgv1Finished = false in OnBeginPrint and now it prints everything.
I am in the process of developing an app that will be later integrated with another app I developed some time ago.
Basically, this app will generate an image file of X and Y dimensions with a grid printed on it, of which the user also specifies it's interval.
I've done this form so far, but I am having difficulty deciding what the best way to generate an actual image with the proper dimensions and grid spacing should be.
I don't want to save the image that is displayed on the form because it is only a representation and could very well be extremely dissimilar from the final product.
So I guess my question is, what do you think the best way is to generate a black and white image when I click "save"?
Also, I have no need to see the image being saved, I just want to generate and save it behind the scenes.
Here is the "draw" button click event
private void btnDraw_Click(object sender, EventArgs e)
{
this.Width = 560;
using (g = pb.CreateGraphics())
{
g.Clear(Color.White);
PaintCanvass canvass = new PaintCanvass();
canvass.Width = Convert.ToDouble(tbWidth.Text);
canvass.Height = Convert.ToDouble(tbHeight.Text);
canvass.Resolution = Convert.ToInt32(cbResolution.Text.Substring(0,3));
canvass.UOM = cbUOM.Text;
canvass.Interval = Convert.ToInt32(tbInterval.Text);
Pen pencil = new Pen(Color.Black, 2);
int hpfact = Convert.ToInt32((double)pb.Height / (double)canvass.horizontalLinesQuantity);
int hp = hpfact;
for (int i = 0; i < canvass.horizontalLinesQuantity-1; i++)
{
g.DrawLine(pencil, new Point(0, hp), new Point(pb.Width, hp));
hp = hp + hpfact;
}
int vpfact = Convert.ToInt32((double)pb.Width / (double)canvass.verticalLinesQuantity);
int vp = vpfact;
for (int i = 0; i < canvass.verticalLinesQuantity-1; i++)
{
g.DrawLine(pencil, new Point(vp, 0), new Point(vp, pb.Height));
vp = vp + vpfact;
}
canvass = null;
And here is my PaintCanvass class which seems to just be ending up as a container for properties for now
class PaintCanvass
{
public double Width { get; set; }
public double Height { get; set; }
public string UOM { get; set; }
public int Resolution { get; set; }
public int Interval { get; set; } = 50;
public int hdots
{
get
{
if (this.UOM == "mm")
{
return Convert.ToInt32(Width * 0.03937008F * Resolution);
}
else
{
return Convert.ToInt32(Width * Resolution);
};
}
}
public int vdots
{
get
{
// Set the quantity of lines
if (this.UOM == "mm")
{
return Convert.ToInt32(Height * 0.03937008F * Resolution);
}
else
{
return Convert.ToInt32(Height * Resolution);
};
}
}
public int horizontalLinesQuantity
{
get
{
return vdots / this.Interval;
}
}
public int verticalLinesQuantity
{
get
{
return hdots / this.Interval;
}
}
}
Edit: as suggested I went with the bitmap method.
private void btnSave_Click(object sender, EventArgs e)
{
SetupCanvass();
using (Bitmap bmp = new Bitmap(canvass.hdots, canvass.vdots))
{
using (Graphics g = Graphics.FromImage(bmp))
{
using (SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255)))
{
g.FillRectangle(brush, 0, 0, canvass.hdots, canvass.vdots);
}
int hp = canvass.Interval;
for (int i = 0; i < canvass.horizontalLinesQuantity - 1; i++)
{
g.DrawLine(pencil, new Point(0, hp), new Point(canvass.hdots, hp));
hp = hp + canvass.Interval;
}
int vp = canvass.Interval;
for (int i = 0; i < canvass.verticalLinesQuantity - 1; i++)
{
g.DrawLine(pencil, new Point(vp, 0), new Point(vp, canvass.vdots));
vp = vp + canvass.Interval;
}
}
bmp.Save(Path.Combine(Path.GetTempPath(), "labelGrid.png")); //Save image somwhere on disk
}
}
If you want to save an image without displaying a preview, just do something like this:
using (Bitmap bmp = new Bitmap(500, 500))
{
using (Graphics g = Graphics.FromImage(bmp))
{
//Draw your stuff directly onto the bitmap here
}
bmp.Save("C:\\image.bmp"); //Save image somwhere on disk
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I'm currently working on an exercise for my c# class. I am having some trouble with one particular part and would really appreciate some help.
I am working on an exercise in which we are given an incomplete project file.
The project has multiple classes, this class is for controlling squares that are placed on the board.
namespace HareAndTortoise {
public partial class SquareControl : PictureBox {
public const int SQUARE_SIZE = 100;
private Square square; // A reference to the corresponding square object
private BindingList<Player> players; // References the players in the overall game.
private bool[] containsPlayers = new bool[6];//HareAndTortoiseGame.MAX_PLAYERS];
public bool[] ContainsPlayers {
get {
return containsPlayers;
}
set {
containsPlayers = value;
}
}
// Font and brush for displaying text inside the square.
private Font textFont = new Font("Microsoft Sans Serif", 8);
private Brush textBrush = Brushes.White;
public SquareControl(Square square, BindingList<Player> players) {
this.square = square;
this.players = players;
// Set GUI properties of the whole square.
Size = new Size(SQUARE_SIZE, SQUARE_SIZE);
Margin = new Padding(0); // No spacing around the cell. (Default is 3 pixels.)
Dock = DockStyle.Fill;
BorderStyle = BorderStyle.FixedSingle;
BackColor = Color.CornflowerBlue;
SetImageWhenNeeded();
}
private void SetImageWhenNeeded()
{
if (square is Square.Win_Square)
{
LoadImageFromFile("Win.png");
textBrush = Brushes.Black;
}
else if (square is Square.Lose_Square)
{
LoadImageFromFile("Lose.png");
textBrush = Brushes.Red;
}
else if (square is Square.Chance_Square)
{
LoadImageFromFile("monster-green.png");
}
else if (square.Name == "Finish")
{
LoadImageFromFile("checkered-flag.png");
}
else
{
// No image needed.
}
}
private void LoadImageFromFile(string fileName) {
Image image = Image.FromFile(#"Images\" + fileName);
Image = image;
SizeMode = PictureBoxSizeMode.StretchImage; // Zoom is also ok.
}
protected override void OnPaint(PaintEventArgs e) {
// Due to a limitation in WinForms, don't use base.OnPaint(e) here.
if (Image != null)
e.Graphics.DrawImage(Image, e.ClipRectangle);
string name = square.Name;
// Create rectangle for drawing.
float textWidth = textFont.Size * name.Length;
float textHeight = textFont.Height;
float textX = e.ClipRectangle.Right - textWidth;
float textY = e.ClipRectangle.Bottom - textHeight;
RectangleF drawRect = new RectangleF(textX, textY, textWidth, textHeight);
// When debugging this method, show the drawing-rectangle on the screen.
//Pen blackPen = new Pen(Color.Black);
//e.Graphics.DrawRectangle(blackPen, textX, textY, textWidth, textHeight);
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Far; // Right-aligned.
// Draw string to screen.
e.Graphics.DrawString(name, textFont, textBrush, drawRect, drawFormat);
// Draw player tokens (when any players are on this square).
const int PLAYER_TOKENS_PER_ROW = 3;
const int PLAYER_TOKEN_SIZE = 30; // pixels.
const int PLAYER_TOKEN_SPACING = (SQUARE_SIZE - (PLAYER_TOKEN_SIZE * PLAYER_TOKENS_PER_ROW)) / (PLAYER_TOKENS_PER_ROW - 1);
for (int i = 0; i < containsPlayers.Length; i++) {
if (containsPlayers[i]) {
int xPosition = i % PLAYER_TOKENS_PER_ROW;
int yPosition = i / PLAYER_TOKENS_PER_ROW;
int xPixels = xPosition * (PLAYER_TOKEN_SIZE + PLAYER_TOKEN_SPACING);
int yPixels = yPosition * (PLAYER_TOKEN_SIZE + PLAYER_TOKEN_SPACING);
Brush playerTokenColour = players[i].PlayerTokenColour;
e.Graphics.FillEllipse(playerTokenColour, xPixels, yPixels, PLAYER_TOKEN_SIZE, PLAYER_TOKEN_SIZE);
}
}//endfor
}
}
}
The program trips up at:
else if (square.Name == "Finish")
{
LoadImageFromFile("checkered-flag.png");
}
I know it is because of square.name but from going through the code, I cant see why square.Name is not recognizable.
Square is passed from another class using this method
private void SetUpGuiGameBoard()
{
for (int i = 0; i <= 55; i++)
{
Square q = Board.GetGameBoardSquare(i);
SquareControl sq = new SquareControl(q, null);
int coloumn;
int row;
if (i == 0)
{
BackColor = Color.BurlyWood;
}
if (i == 55)
{
BackColor = Color.BurlyWood;
}
MapSquareNumToTablePanel(i, out coloumn, out row);
tableLayoutPanel1.Controls.Add(sq, coloumn, row);
}
and Squares are created in this class
private static Square[] gameBoard = new Square[56];
static public void SetUpBoard()
{
for (int i = 1; i == 55; i++)
{
gameBoard[i] = new Square("Ordinary Square", i);
}
gameBoard[0] = new Square("Start", 0);
gameBoard[4] = new Square.Lose_Square("Lose Square", 4);
gameBoard[5] = new Square.Chance_Square("Chance Square", 5);
gameBoard[9] = new Square.Win_Square("Win Square", 9);
gameBoard[11] = new Square.Chance_Square("Chance Square", 11);
gameBoard[14] = new Square.Lose_Square("Lose Square", 14);
gameBoard[17] = new Square.Chance_Square("Chance Square", 17);
gameBoard[19] = new Square.Win_Square("Win Square", 19);
gameBoard[24] = new Square.Lose_Square("Lose Square", 24);
gameBoard[29] = new Square.Win_Square("Win Square", 29);
gameBoard[34] = new Square.Lose_Square("Lose Square", 34);
gameBoard[35] = new Square.Chance_Square("Chance Square", 35);
gameBoard[39] = new Square.Win_Square("Win Square", 39);
gameBoard[44] = new Square.Lose_Square("Lose Square", 44);
gameBoard[47] = new Square.Chance_Square("Chance Square", 47);
gameBoard[49] = new Square.Win_Square("Win Square", 49);
gameBoard[53] = new Square.Chance_Square("Chance Square", 53);
gameBoard[55] = new Square("Finish", 56);
}
public static Square GetGameBoardSquare(int n)
{
return gameBoard[n];
}
public static Square StartSquare()
{
return gameBoard[0];
}
public static Square NextSquare(int n)
{
return gameBoard[(n+1)];
}
}
The answer already provided is the best way for prevention of any null reference exception. For more clarification I can suggest you to check the call stack at the point the debugger reaches the SquareControl constructor. At this point you should check why the Square object being passed in is a 'NULL'. That will lead you to the root cause of the problem. Hope this helps.
I have a custom CheckListBox control that is supposed to function the same way as the CheckedListBox control but it is not. The problem is when I scroll down, the drawing gets all messed up. The container won't actually scroll down, it will just "jitter" the check boxes around, draw random lines, etc.
Update: I changed the code so the location of each CheckBox was set in the OnControlAdded method instead of the OnPaint method. It now scrolls fine, but the drawing is still messed up! The border is missing, the BackColor changes, the lines for the check boxes are not straight; just a whole mess of things. It works perfectly in the designer (the scrolling and drawing), but not when I run the program.
Here's the code for the control:
public class ChromeCheckListBox : ChromeContainerControl
{
[Description("Determines what corner(s) will be rounded.")]
public Utilities.RoundedRectangle.RectangleCorners Corners { get; set; }
private int cornerRadius;
[Description("Determines the radius of the the corners")]
public int CornerRadius
{
get { return cornerRadius; }
set
{
if (value < 1)
Utilities.ThrowError("The radius cannot be less than 1. If you want no radius, set Corners to None.");
else
cornerRadius = value;
}
}
[Description("Determines the list of ChromeRadioButton controls that are displayed.")]
private ChromeCheckBox[] items;
public ChromeCheckBox[] Items
{
get { return items; }
set
{
items = value;
Controls.Clear();
Controls.AddRange(items);
}
}
public ChromeCheckListBox()
{
this.AutoScroll = true;
this.Corners = Utilities.RoundedRectangle.RectangleCorners.All;
this.CornerRadius = 1;
this.Items = new ChromeCheckBox[0];
this.Size = new Size(100, 100);
}
protected override void OnControlAdded(ControlEventArgs e)
{
for (int i = 0; i < Items.Length; i++)
{
if (i == 0)
Items[i].Location = new Point(2 + Padding.Left, 2 + Padding.Top);
else
Items[i].Location = new Point(2 + Padding.Left, Items[i - 1].Location.Y + Size.Ceiling(this.CreateGraphics().MeasureString(Items[i - 1].Text, Items[i - 1].Font)).Height);
}
base.OnControlAdded(e);
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics canvas = e.Graphics;
canvas.SmoothingMode = SmoothingMode.HighQuality;
Rectangle region = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
GraphicsPath path = Utilities.RoundedRectangle.Create(region, CornerRadius, Corners);
canvas.FillPath(new LinearGradientBrush(region, fillColors[0], fillColors[1], 90), path);
canvas.DrawPath(new Pen(borderColor), path);
}
}
I got it! Instead of setting the location of the check boxes in the OnPaint method, I should set them in the OnControlAdded method. Also, on the OnScroll method, I need to Invalidate the control causing it to redraw.
So, it should (well maybe not should, but could) look like this:
public class ChromeCheckListBox : ChromeContainerControl
{
[Description("Determines what corner(s) will be rounded.")]
public Utilities.RoundedRectangle.RectangleCorners Corners { get; set; }
private int cornerRadius;
[Description("Determines the radius of the the corners")]
public int CornerRadius
{
get { return cornerRadius; }
set
{
if (value < 1)
Utilities.ThrowError("The radius cannot be less than 1. If you want no radius, set Corners to None.");
else
cornerRadius = value;
}
}
[Description("Determines the list of ChromeRadioButton controls that are displayed.")]
private ChromeCheckBox[] items;
public ChromeCheckBox[] Items
{
get { return items; }
set
{
items = value;
Controls.Clear();
Controls.AddRange(items);
}
}
public ChromeCheckListBox()
{
this.AutoScroll = true;
this.Corners = Utilities.RoundedRectangle.RectangleCorners.All;
this.CornerRadius = 1;
this.Items = new ChromeCheckBox[0];
this.Size = new Size(100, 100);
}
protected override void OnControlAdded(ControlEventArgs e)
{
for (int i = 0; i < Items.Length; i++)
{
if (i == 0)
Items[i].Location = new Point(2 + Padding.Left, 2 + Padding.Top);
else
Items[i].Location = new Point(2 + Padding.Left, Items[i - 1].Location.Y + Size.Ceiling(this.CreateGraphics().MeasureString(Items[i - 1].Text, Items[i - 1].Font)).Height);
}
base.OnControlAdded(e);
}
protected override void OnScroll(ScrollEventArgs se)
{
base.OnScroll(se);
base.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics canvas = e.Graphics;
canvas.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle region = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
GraphicsPath path = Utilities.RoundedRectangle.Create(region, CornerRadius, Corners);
canvas.FillPath(new LinearGradientBrush(region, fillColors[0], fillColors[1], 90), path);
canvas.DrawPath(new Pen(borderColor), path);
}