I'm working on a code editor and I just want to know how to do codes in counting Lines and Columns in richtextbox. Particularly something like this one in actual code editor:
Let's just say count will transfer in a ListBox.
Is there a fast way I can do it?
You can do this :
//This to get lines number.
int index = richTextBox.SelectionStart;
int li = richTextBox.GetLineFromCharIndex(index);
// This to get columns number.
int firstChar = richTextBox.GetFirstCharIndexFromLine(li);
int col = index - firstChar;
Good luck!
This will do it, you just have to call the code inside a timer:
int line = 1 + richTextBox1.GetLineFromCharIndex(richTextBox1.GetFirstCharIndexOfCurrentLine());
int column = 1 + richTextBox1.SelectionStart - richTextBox1.GetFirstCharIndexOfCurrentLine();
label1.Text = "line: " + line.ToString() + ", column: " + column.ToString();
Related
I have a 3x3 matrix that I want to populate (may grow to 3x4 or 3x5 but not larger). Very simple with a dual for loop except that each row has a unique formula and each column has a unique column within the formula.
I started trying to create for loops, case statements, but ended up just brute force updating each cell.
Then I thought maybe some master crafter has some ideas. Is there any way to make this simpler:
myWorksheet.Cells[1, 1].Formula = "=ROUND(AVERAGE(B$2:B$" + counter + "), 3)";
myWorksheet.Cells[1, 2].Formula = "=ROUND(AVERAGE(C$2:C$" + counter + "), 3)";
myWorksheet.Cells[1, 3].Formula = "=ROUND(AVERAGE(D$2:D$" + counter + "), 3)";
myWorksheet.Cells[2, 1].Formula = "=MAX(B$2:B$" + counter + ")";
myWorksheet.Cells[2, 2].Formula = "=MAX(C$2:C$" + counter + ")";
myWorksheet.Cells[2, 3].Formula = "=MAX(D$2:D$" + counter + ")";
myWorksheet.Cells[3, 1].Formula = "=STDEV(B$2:B$" + counter + ")";
myWorksheet.Cells[3, 2].Formula = "=STDEV(C$2:C$" + counter + ")";
myWorksheet.Cells[3, 3].Formula = "=STDEV(D$2:D$" + counter + ")";
Your formula has three portions, the function name, the argument, and the closing. You can make a method that will create the formula to insert based on the cell's row and column coordinates.
public static string RenderFormula(int row, int column, int counter)
{
var stringBuilder = new StringBuilder();
stringBuilder.Append("=");
// part 1 - the function name
var methodName = row switch
{
1 => "ROUND(AVERAGE(",
2 => "MAX(",
3 => "STDEV(",
_ => throw new ArgumentException(nameof(row))
};
stringBuilder.Append(methodName);
// part 2 - the argument
char rangeColumnLetter = (char)('A' + column);
var range = $"{rangeColumnLetter}$2:{rangeColumnLetter}${counter}";
stringBuilder.Append(range);
// part 3 - the closing
var methodEnding = row switch
{
1 => "), 3)",
2 or 3 => ")",
_ => throw new ArgumentException(nameof(row))
};
stringBuilder.Append(methodEnding);
return stringBuilder.ToString();
}
In part one, you know which excel function to use based on the row number.
In part two, you add the column number to a capital "A" to get the new range column letter. This means that (column 1 + "A" = "B"). Add the value of counter into it.
In part three, you need to close the function's parentheses. Row 1 formulas have two closing parentheses with another argument in the middle, so account for it.
This uses StringBuilder to avoid a lot of wasteful concatenations.
Then just call the method to find out what the formula to insert is.
Console.WriteLine(RenderFormula(1, 1, 50));
Console.WriteLine(RenderFormula(2, 2, 50));
Console.WriteLine(RenderFormula(3, 3, 50));
// =ROUND(AVERAGE(B$2:B$50), 3)
// =MAX(C$2:C$50)
// =STDEV(D$2:D$50)
My main code is below:
Mtb.Application MtbApp = new Mtb.Application();
MtbApp.UserInterface.Visible = true;
MtbApp.UserInterface.DisplayAlerts = false;
Mtb.Project MtbProj = MtbApp.ActiveProject;
Mtb.Columns MtbColumns;
Mtb.Column MtbColumn1;
Double[] data1;
Hashtable htSingleColumn;
List<double> listSingleColumn;
int i = 1 ;
foreach (DictionaryEntry de in htDataTable)
{
htSingleColumn = (Hashtable)de.Value;
listSingleColumn = (List<double>)htSingleColumn["listSingleData"];
data1 = listSingleColumn.ToArray();
MtbColumns = MtbProj.ActiveWorksheet.Columns;
MtbColumn1 = MtbColumns.Add(null, null, i);
MtbColumn1.SetData(data1);
// strLowlim and strUpplim have no influence on this issue here
strCommand = "Capa C" + i+" 1;" + ((strLowlim == "NA") ? "" : (" Lspec " + strLowlim + ";")) +((strUpplim == "NA") ? "" : (" Uspec " + strUpplim + ";"))+ " Pooled; AMR; UnBiased; OBiased; Toler 6; Within; Percent; CStat.";
// The program is crashing here as a result of the columns not being created sequentially
MtbProj.ExecuteCommand(strCommand);
Mtb.Graph MtbGraph = MtbProj.Commands.Item(i).Outputs.Item(1).Graph;
MtbGraph.SaveAs("C:\\MyGraph" + DateTime.Now.ToString("yyyy-MM-dd HHmmss"), true, Mtb.MtbGraphFileTypes.GFPNGHighColor);
i++;
}
MtbApp.Quit();
When running this code (with the crashing section commented out), I get the following output:
It should look like this:
I am really puzzled about this result. The variable i is right, but what is affecting the column number?
I can't find much information on the Web about Minitab. I just read the start guide here.
This line is the problem.
MtbColumn1 = MtbColumns.Add(null, null, i);
The third parameter Quantity specifies the number of columns to add. On the first iteration of the loop, you add i = 1 column, but on the second iteration of the loop you add i = 2 columns. Each iteration of the loop will add an additional i columns, when what you really want is to add one column each time.
Change the line to:
MtbColumn1 = MtbColumns.Add();
I have a list of input curve names in a text file called inCurves.txt. The .txt file reads:
18500*8500*Eval:c3*Eval:c2*Eval:c1*Final:DTS*Final:OBG*Final:PPG*
The first two numbers are bottom and top depth, while the remainder are curveSet names and curve names for every remaining comboBox (1 - 6)
I've written a script to populate comboBoxes from this .txt, but I receive an error when I try to convert cmbBox into string, and then into an integer.
input string was not in a correct format)
private void btnLoad_Click(object sender, EventArgs e)
{
try
{
string CurveNamesInText = "";
char[] delimiter = { '*' };
CurveNamesInText = System.IO.File.ReadAllText(#"C:\Users\Public\inCurves.txt");
string[] crvIn = CurveNamesInText.Split(delimiter);
string BottomDepth = crvIn[0];
string TopDepth = crvIn[1];
var combBoxes = this.Controls.OfType<ComboBox>().Where(x => x.Name.StartsWith("comboBox"));
foreach (var cmbBox in combBoxes)
{
string yes = Convert.ToString(cmbBox);
string number = yes.Replace("comboBox","0");
int i = Convert.ToInt16(number); //error here, comp doesn't like it
MessageBox.Show("current number value \n" + number + "\n" + "current i value \n" + i);
//cmbBox.Text = crvIn[6-i]; // this is what I'd like to do next
}
}
catch (Exception ex)
{
MessageBox.Show("Error Loading Curve names \n" + ex.Message + "\n" + ex.StackTrace);
}
}
I would like to assign an element in crvIn list to each comboBox. Ideally, something like this:
cmbBox.Text = crvIn[i];
Can you help?
The problem is that you are trying to convert an entire object ComboBox into a string, which will result only in the full name of the class/type ComboBox plus the item count:
"System.Windows.Controls.ComboBox Items.Count:0"
You can also see this in the Debugger.
I would like to assign an element in crvIn list to each comboBox
I guess if you want to add each value to a different combobox you could use a for-loop and add the items. You need to add it to the items, if you want to make them selectable.
First you need to make a list from your query. Add ToList() at the end:
var combBoxes = this.Controls.OfType<ComboBox>()
.Where(x => x.Name.StartsWith("comboBox")).ToList();
for (int i = 0; i < combBoxes.Count; i++)
{
combBoxes[i].Text = crvIn[i + 2];
}
for (int i = 0; i < richTextBox2.Lines.Length; i++)
{
richTextBox2.Lines[i] = richTextBox2.Lines[i].Insert(0, i + " ");
}
Before that tried with the Insert:
richTextBox2.Lines[i].Insert(0, i + " ");
In both cases it's not adding any numbers.
For example if the lines are:
Hello world
Hi
Hello
Then i want it to be now:
1 Hello world
2 Hi
3 Hello
But the loop does nothing it's not adding any numbers.
You can't modifiy the single line in that way. If you look at MSDN you will find this remark
By default, the collection of lines is a read-only copy of the lines
in the TextBox. To get a writable collection of lines, use code
similar to the following: textBox1.Lines = new string[] { "abcd" };
So the correct way to reach you goal is
string[] lines = richTextBox2.Lines;
for (int i = 0; i < lines.Length; i++)
{
lines[i] = (i+1) + " " + lines[i];
}
richTextBox2.Lines = lines;
You can try using Linq:
using System.Linq;
...
richTextBox2.Lines = richTextBox2
.Lines
.Select((line, index) => $"{index + 1} {line}")
.ToArray();
please, avoid redrawing UI (esp. RichTextBox) which can slow down your application, but build the data (lines, text) and then assign it in one go.
I am trying to print output from a custom structure into Excel file. What I am trying to do is:
COLUMN NAME
PLAYER
PLAYER
COLUMN NAME
PLAYER
PLAYER
But What I am getting is
COLUMN NAME
COLUMN NAME
PLAYER
PLAYER
CODE:
int i = 1;
foreach (var item in scoresheet.Positions)
{
var column = wb.Cells;
if ((i % 5) == 1)
{
column["A" + i].LoadFromText("Initial Rank");
}
else
{
column["A" + i + 1].LoadFromText(item.Player.FirstName);
}
i++;
}
Looking at your line:
column["A" + i + 1].LoadFromText(item.Player.FirstName);
I assume you want that to be, say, a result of "A2" when i is equal to 1. BUT, what you will actually end up with is "A11" since it will do it as a string concatenation. What you need is:
column["A" + (i + 1)].LoadFromText(item.Player.FirstName);