String alignment without monospaced font - c#

I want an aligned string across multiple rows in a right-click menu in excel. The right click menu is added like this:
CommandBar contextMenu = Globals.ThisWorkbook.Application.CommandBars["List Range Popup"];
CommandBarPopup subMenu = (CommandBarPopup)contextMenu.Controls.Add(Type: MsoControlType.msoControlPopup, Before: 1, Temporary: true);
subMenu.Caption = "Assumptions Drill Down";
I then iterate database results and add to the subMenu in the proceeding rows
Current result as below (using string padding):
As the character spaces are not even (non-monospaced font) the columns are not aligned. I've tried to do something like the below to get the pixel size of the string and then covert back to the required string padding integer but I cant get it to work:
private static double GetStringSize(string stringText)
{
Bitmap b = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(b);
SizeF size = g.MeasureString(stringText,
new System.Drawing.Font("Calibri", 10, FontStyle.Regular, GraphicsUnit.Point));
return size.Width;
}
Is there a way to set font on a right click to monospaced (i dont believe so)
If I cant do (1.) how can I make sure spacing in each column is even - so for example evenly align a user of 'iiiii' vs 'QQQQQ'
?

Related

how to check whether a string can fit into richtextbox visible area

I want to divide a very large string into slices so that each slice can fit into the visible area of a richtextbox so that the horizontal scroll bar will not show.
I would like to know how to determine whether a string can fit into the richtextbox's visible area without changing the richtextbox's value.
I searched for the solution and most results I found suggest that MeasureText / MeasureString should be used, but it seems these two function assume there is only one line(not wrapped).
Is there any way to find out the height of a multiple line string which will be set into a richtextbox?
MeasureText and MeasureString functions has overloads that accept textarea width, height and TextFormatFlags(TextBoxControl, WordBreak e.t.c)
You can compare your text size with RichTextBoxControl size
Size stringSize = new Size();
string text = SomeText();
stringSize = TextRenderer.MeasureText(text, richTextBox1.Font, new Size(richTextBox1.Size.Width, richTextBox1.Size.Height), TextFormatFlags.WordBreak);
string r = string.Format("RTB Width : {0}\r\n", richTextBox1.Size.Width);
r += string.Format("RTB Height : {0}\r\n", richTextBox1.Size.Height);
r += string.Format("TEXT Width : {0}\r\n", stringSize.Width);
r += string.Format("TEXT Height : {0}", stringSize.Height);
MessageBox.Show(r);

C# DataGridView visual settings

I'm look for a way to make some changes to the DataGridview in C# shown in this picture:
It consists of two columns and in this case 6 rows.
It's supposed to be an checklist, you are reading: "Battery....ON" and so on.
To get the dots between the Left and right column, I'm simply adding many dot's after and in front of each string.
The Battery string looks like this:
"BATTERY...............................".
The "ON" string on the right column would look like this:
"..............ON"
As you can see, there is still a gap between the dots, how do I get rid of this?
CellBorderStyle ist set to:
checklist_dataGridView.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
Additionally, there is a slight height difference between the left and right column, this is the result of
checklist_dataGridView.Columns[1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
This is supposed to to make the right column text go from right to left.
Without this, the right column would only show "..........................."
Is there any better way to align everything properly?
Thanks for your help
Axel R
Edit:
I've solved the problem by making a single column and simply counting the width of the string. If the string has not reached the width of the column, there will be one dot added to the string. This works very well for me.
You could get close to the layout you want by using custom cell painting of the gridlines. You could custom paint the bottom gridlines as a green dotted line and skip adding the dots to the cell values. The only difference is that the lines would go across the entire grid horizontally.
First make sure the left column is bottom left aligned, and the right column is bottom right aligned:
checklist_dataGridView.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomLeft;
checklist_dataGridView.Columns[0].DefaultCellStyle.ForeColor = System.Drawing.Color.LightGreen;
checklist_dataGridView.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomRight;
checklist_dataGridView.Columns[1].DefaultCellStyle.ForeColor = System.Drawing.Color.LightGreen;
To custom paint the cells with a dotted green line on the bottom, you can implement a DataGridView CellPainting handler:
private void checklist_dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex > -1 )
{
e.Handled = true;
e.Graphics.FillRectangle(System.Drawing.Brushes.Black, e.CellBounds);
using (Pen p = new Pen(Brushes.LightGreen))
{
p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
e.Graphics.DrawLine(p, new Point(0, e.CellBounds.Bottom - 1), new Point(e.CellBounds.Right, e.CellBounds.Bottom - 1));
}
e.PaintContent(e.ClipBounds);
}
}
Sorry... you can't get rid of the gap because the checklist_dataGridView.DefaultCellStyle.Padding = new Padding(0, 0, 0, 0); doesn't take negative values.
Now to make your original code work I will just add a space dot space dot space dot like " . . . . . . . . ."
This way you don't see just the dots on the cell and the text will get wrapped around. Also if you end with a dot on the left cell and start with a dot on the right cell then the gap will be close to the space distance and it will be less noticeable.
Don't forget this so your text wraps:
checklist_dataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
checklist_dataGridView.DefaultCellStyle.WrapMode = DataGridViewTriState.True;

C# Pen.DashPattern

I want to draw a Line between 2 rows while using drag and drop. The function of this is simply visual, so that the user knows, where he is dropping the row. The line should look like the excel onces. Here my code:
Pen _marqueePen = new Pen(Color.Gray, 2);
float[] dashValues = {1f,1f};
_marqueePen.DashPattern = dashValues;
But this looks like that
I want to look it like that:
I'm WinForms and the C1 Flexgrid control.
You can use a Custom Pen like this:
using (Pen pen = new Pen(Color.Gray, 4f) )
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
pen.DashPattern = new float[] { 0.25F, 0.25F };
// now draw your stuff..
}
Note the doc on MSDN:
The elements in the dashArray array set the length of each dash
and space in the dash pattern. The first element sets the length of a dash,
the second element sets the length of a space, the third element sets
the length of a dash, and so on. Consequently, each element should be a
non-zero positive number.
The length of each dash and space in the dash pattern is the product
of the element value in the array and the width of the Pen.
You can pick any pen width and any dash&gap lengths as long as you keep their relation in mind.. So if you want the finest dashes, make sure they multiply to 1.0 pixels!
Here is the resulting line:
Some options:
You could use a PNG graphic that mimics that excel behaviour and then draw it on the control (you'll have to tile your image vertically).
Draw three lines with your code, with offset of y-axis & x-axis one pixel.
That looks to me more like a rectangle filed with HatchBrush having HatchStyle.Percent50 and height of 3.
You could try
Rectangle rect = new Rectangle(0, 0, 500, 3) //you will use the values here from your cursor but height will be 3
HatchBrush brush = new HatchBrush(HatchStyle.Percent50, Color.Black);
g.FillRectangle(brush, rect);

How to AutoSize the height of a Label but not the width

I have a Panel that I'm creating programmatically; additionally I'm adding several components to it.
One of these components is a Label which will contain user-generated content.
I don't know how tall the label should be, but it does have a fixed width.
How can I set the height so that it displays all the text, without changing the width?
Just use the AutoSize property, set it back to True.
Set the MaximumSize property to, say, (60, 0) so it can't grow horizontally, only vertically.
Use Graphics.MeasureString:
public SizeF MeasureString(
string text,
Font font,
int width
)
The width parameter specifies the
maximum value of the width component
of the returned SizeF structure
(Width). If the width parameter is
less than the actual width of the
string, the returned Width component
is truncated to a value representing
the maximum number of characters that
will fit within the specified width.
To accommodate the entire string, the
returned Height component is adjusted
to a value that allows displaying the
string with character wrap.
In other words, this function can calculate the height of your string based on its width.
If you have a label and you want have control over the the vertical fit, you can do the following:
MyLabel.MaximumSize = new Size(MyLabel.Width, 0)
MyLabel.Height = MyLabel.PreferredHeight
MyLabel.MaximumSize = new Size(0, 0)
This is useful for example if you have a label in a container that can be resized. In that case, you can set the Anchor property so that the label is resized horizontally but not vertically, and in the resize event, you can fit the height using the method above.
To avoid the vertical fitting to be interpreted as a new resize event, you can use a boolean:
bool _inVerticalFit = false;
And in the resize event:
if (_inVerticalFit) return;
_inVerticalFit = true;
MyLabel.MaximumSize = new Size(MyLabel.Width, 0)
MyLabel.Height = MyLabel.PreferredHeight
MyLabel.MaximumSize = new Size(0, 0)
_inVerticalFit = false;

Define different font size for text and line spacing and create an image from it using C# [duplicate]

This question already has answers here:
How to set line spacing Graphics.DrawString
(2 answers)
Closed 5 years ago.
I know how to create an image from text in C# and how to specify a certain font size for the text. But, I want to be able to have a few lines of text where the text is one font size - but the line spacing is a smaller font size - and be able to create an image from this in C#.
For example, I have three lines of text. The font size for each text line is 24 (not sure what the unit is - pixels? point?). But, I want the line spacing between each text line to only be 8.
Does anyone know how this can be accomplished?
Try to draw each line separately and define its vertical position as vertical position of the previous line plus your desired spacing.
var left = 0;
var top = 0;
var myFontSize = 12;
var mySpacing = 8;
var myFont = new Font("MyFontFamily", myFontSize);
var myBrush = Brushes.Black;
var myLines = new List<string>{
// your strings here
};
for(var i = 0; i < myLines.Count; i++)
{
var lineText = myLines[i];
// this line is needed to get line size in pixels, regardless in which units font size is specified
// also different fonts can have different image sizes for the same font size
var lineImageSize = graphics.MeasureString(lineText, myFont);
graphics.DrawString(myLines[i], myFont, myBrush, left, top + (i * (lineImageSize.Height + mySpacing)));
}

Categories

Resources