Go To Line in Text Editor - c#

I tried implementing GoTo ling in a basic editor-type app but isn't always accurate. More often than not, it gets the right line, but it seems that the more lines there are, the more of a chance it will get the line position wrong and go to the wrong line. Not sure why this isn't working. Can someone please help?
int position = 0;
int lineCount = ((TextBox)tabControl1.SelectedTab.Controls[0]).Lines.Count();
for (int i = 0; i < LineNumber; i++)
{
position += ((TextBox)tabControl1.SelectedTab.Controls[0]).Lines[i].Count();
}
((TextBox)tabControl1.SelectedTab.Controls[0]).Focus();
((TextBox)tabControl1.SelectedTab.Controls[0]).SelectionStart = position;
((TextBox)tabControl1.SelectedTab.Controls[0]).ScrollToCaret();
LineNumber = 0;
position = 0;
lineCount = 0;

I am not sure if I have understood you correctly, but a TextBox control has a method called
TextBoxBase.GetFirstCharIndexFromLine
So if your user wants to go to line 10 (and you have 10 lines) then
int pos = textBox1.GetFirstCharIndexFromLine(9);
textBox1.SelectionStart = pos;
textBox1.ScrollToCaret();

I think #Steve has got you covered with TextBox.GetFirstCharIndexFromLine().
In your original code, though, I think you just needed to account for the carriage return / line feeds at the end of each line (they aren't included when access each line thru the Lines() property). This example assumes the desired line # is 1 (one) based:
int LineNumber = 6;
TextBox TB = (TextBox)tabControl1.SelectedTab.Controls[0];
int position = 0;
for (int i = 1; i <= TB.Lines.Length && i < LineNumber; i++)
{
position += TB.Lines[i - 1].Length + Environment.NewLine.Length;
}
TB.Focus();
TB.SelectionStart = position;
TB.SelectionLength = 0;
TB.ScrollToCaret();

Related

How can I have x many symbols on the first line then adding 1 more each line until it hits the end value with a for loop?

So I want to recreate this process with a for loop. What's the simplest way of doing this. I can do 1 to 10 but let's say you have 3 as your start value I can't get the first line to start with 3 symbols.
Thanks in advance.
Since you haven't shared any code, I'll give you an idea as to how you can print the values. I've used 2 for loops to print the value. Although there maybe better and shorter algorithms to do the same
Just edit my code below to suit your needs.
public static void Main()
{
var start = 3; //StartTextBox.Text
var end = 10; //EndTextBox.Text
var symbol = "#"; //SymbolTextBox.Text
for (var i = start; i < end; i++)
{
var toPrint = string.Empty;
for (var j = 0; j < i; j++) toPrint += symbol;
Console.WriteLine(toPrint); //LabelX.Text = toPrint;
}
Console.ReadLine();
}
You can see in the above code that if you change the value of start to any number, the value gets printed properly.
Another option assuming some of your object names...
for (int i = int.Parse(txtStart.Text); i <= int.Parse(txtEnd.Text); i++)
{
lblOutput.Text += new String(txtSymbol.Text.ToCharArray()[0], i) + Environment.NewLine;
}

Is it possible to have smoother contour lines with the ContourSeries in OxyPlot?

I used OxyPlot for drawing contours, but they seem a little rough at some places, so I would need to smooth them. So, I was wondering if it was possible to smooth the contour with OxyPlot or if I will need something else?
I know that you can smooth the LineSeries, so by looking inside the code for the LineSeries I have tried to put the code for smoothing in the ContourSeries, but I am not quite able to figure out how everything works. I tried to find smoothing algorithm on the internet, but I wasn't able to find many and those that I tried didn't work at all.
Also, I have tried to look for another library for drawing contours, but OxyPlot seems to be the best for free for WPF, but if you have other suggestions that can give me better results I would appreciate it.
After some more searching I found an algorithm that did a pretty good job, but some lines that needed to be closed were not, but the performance were really good by comparing to other algorithms I tried.
Here's the algorithm
private void SmoothContour(List<DataPoint> points, int severity = 1)
{
for (int i = 1; i < points.Count; i++)
{
var start = (i - severity > 0 ? i - severity + 1 : 0);
var end = (i + severity < points.Count ? i + severity + 1 : points.Count);
double sumX = 0, sumY = 0;
for (int j = start; j < end; j++)
{
sumX += points[j].X;
sumY += points[j].Y;
}
DataPoint sum = new DataPoint(sumX, sumY);
DataPoint avg = new DataPoint(sum.X / (end - start), sum.Y / (end - start));
points[i] = avg;
}
}
It's based on this method: https://stackoverflow.com/a/18830268/11788646
After that I put this method in the ContourSeries class like this :
List<Contour> smoothedContours = new List<Contour>();
for (int i = 0; i < contours.Count; i++)
{
List<DataPoint> smoothedPoints = new List<DataPoint>(contours[i].Points);
for (int j = 0; j < SmoothLevel; j++)
{
SmoothContour(smoothedPoints);
}
Contour contour = new Contour(smoothedPoints, contours[i].ContourLevel);
smoothedContours.Add(contour);
}
contours = smoothedContours;
It's located in the CalculateContours() method just after the call of the JoinContourSegments() method. I also added a SmoothLevel property to add more smoothing to the lines. The higher it is the smoother the lines are, but when it is set too high, it doesn't do too well. So I keep at 10 and it's good.

Filling last line in console

I would like to fill/update the entire bottom line of the console. Example:
static void Main(string[] args)
{
Console.BufferWidth = Console.WindowWidth;
Console.BufferHeight = Console.WindowHeight;
Console.CursorTop = Console.WindowHeight - 1;
string s = "";
for(int i = 0; i < Console.BufferWidth; i++)
s += (i%10).ToString();
Console.Write(s);
Console.CursorTop = 0;
Console.ReadKey();
}
The issue is that when the text is printed, it moves to a new line. Similar questions stated to move the cursor to 0,0, however that only works when the buffer size is larger than the window size, and I would like the buffer width and the window width to be equal (to remove scroll bars).
Any ideas? The closest I could get is printing to a higher line and moving it to the last line, however that will not be acceptable in the full project.
Edit:
The last sentence of the question was specifically talking about movebufferarea. The reason why that won't work can be seen by this example:
static void Main(string[] args)
{
Console.BufferWidth = Console.WindowWidth;
Console.BufferHeight = Console.WindowHeight;
while (!Console.KeyAvailable)
{
Console.CursorTop = Console.WindowHeight - 2;
string s = "";
for (int i = 0; i < Console.BufferWidth; i++)
s += (i % 10).ToString();
Console.Write(s);
Console.MoveBufferArea(0, Console.WindowHeight - 2, Console.WindowWidth, 1, 0, Console.WindowHeight - 1);
Thread.Sleep(10);
}
}
The sentence will flicker every so often because it is printed first and then moved.
Since the cursor is always trailing after the text you've written you can either write one less character to avoid going to the next line, or simply write the characters directly into the buffer (I believe, Console.MoveBufferArea can be used for that).
As Joey mentioned, using the MoveBufferArea method will do what you're looking to accomplish:
Console.BufferWidth = Console.WindowWidth;
Console.BufferHeight = Console.WindowHeight;
string s = "";
for (int i = 0; i < Console.BufferWidth; i++)
s += (i % 10).ToString();
Console.Write(s);
//
// copy the buffer from its original position (0, 0) to (0, 24). MoveBufferArea
// does NOT reposition the cursor, which will prevent the cursor from wrapping
// to a new line when the buffer's width is filled.
Console.MoveBufferArea(0, 0, Console.BufferWidth, Console.BufferHeight, 0, 24);
Console.ReadKey();
Here's the result:
Set the BufferHeight and BufferWidth after you've written the string.
Console.CursorTop = Console.WindowHeight - 1;
Console.SetCursorPosition(0, Console.CursorTop);
string s = "";
for (int i = 0; i < Console.BufferWidth; i++)
s += (i % 10).ToString();
Console.Write(s);
Console.CursorTop = 0;
Console.BufferWidth = Console.WindowWidth;
Console.BufferHeight = Console.WindowHeight;
Console.ReadKey();

Setting the cursor's current line on a .NET TextBox

In .NET, you can easily get the line number of the cursor location of a TextBox (i.e. the "current line") by using GetLineFromCharIndex and SelectionStart:
var currentLine = textBox1.GetLineFromCharIndex(textBox1.SelectionStart);
Is there a "clean/native" way to set the cursor in a given line of a Textbox (i.e. set the "current line")? Or at least a "clean/native" way to get the char index of the first character of a given line (something like getCharIndexFromLine, the opposite of the function I put before)?
A way to do it would involve iterating over the first N-1 elements of the Lines property of the TextBox and summing their lengths plus the lengths of the linebreaks. Any other idea?
There is a GetFirstCharIndexFromLine() function that is available:
int myLine = 3;
int pos = textBox1.GetFirstCharIndexFromLine(myLine);
if (pos > -1) {
textBox1.Select(pos, 0);
}
This was the best I could come up with:
private void SetCursorLine(TextBox textBox, int line)
{
int seed = 0, pos = -1;
line -= 1;
if(line == 0) pos = 0;
else
for (int i = 0; i < line; i++)
{
pos = textBox.Text.IndexOf(Environment.NewLine, seed) + 2;
seed = pos;
}
if(pos != -1) textBox.Select(pos, 0);
}
If you want to start counting lines at 0 remove the line -= 1; segment.

IndexOutOfRangeException was unhandled- Index was outside the bounds of the array

I have a for loop that adds items in an array to a listView.
(It'll grab items on a webpage, remove anything after the ' in the string, then add it to the listView)
The error I am getting is: IndexOutOfRangeException was unhandled- Index was outside the bounds of the array
Here's the code I am using:
string[] aa = getBetweenAll(vid, "<yt:statistics favoriteCount='0' viewCount='", "'/><yt:rating numDislikes='");
for (int i = 0; i < listView1.Items.Count; i++)
{
string input = aa[i];
int index = input.IndexOf("'");
if (index > 0)
input = input.Substring(0, index);
listView1.Items[i].SubItems.Add(input);
}
The error occurs on this line: string input = aa[i];
Anything I did wrong? How can I fix this issue so it'll stop happening? Thanks!
If you're wondering the code for the getBetweenAll method is:
private string[] getBetweenAll(string strSource, string strStart, string strEnd)
{
List<string> Matches = new List<string>();
for (int pos = strSource.IndexOf(strStart, 0),
end = pos >= 0 ? strSource.IndexOf(strEnd, pos) : -1;
pos >= 0 && end >= 0;
pos = strSource.IndexOf(strStart, end),
end = pos >= 0 ? strSource.IndexOf(strEnd, pos) : -1)
{
Matches.Add(strSource.Substring(pos + strStart.Length, end - (pos + strStart.Length)));
}
return Matches.ToArray();
}
Your looping the elements of 'listView1'
If the item count of listView1 exceeds the number of elements of the string array 'aa' you will get this error.
I would either change the loop to be
for( ..., i < aa.Length, ...)
or inside your for loop put an if statement to make sure that you are not exceeding the elements of aa. (although, I doubt this is what you want to do).
for (int i = 0; i < listView1.Items.Count; i++)
{
if( i < aa.Length)
{
string input = aa[i];
int index = input.IndexOf("'");
if (index > 0)
input = input.Substring(0, index);
listView1.Items[i].SubItems.Add(input);
}
}
Well it is simple, your ListView.Items.Count is bigger then aa.Length. You need to make sure they have the same size.
Your for loop should be changed to
for (int i = 0; i < aa.Length; i++)
Also, when you do the below line, make sure the index matches.
listView1.Items[i].SubItems.Add(input);
Because of your above error, it seems it does not match, You might be better off looping through your list view to find a matching ListView Item and then maniuplate it.

Categories

Resources