How to replace last comment by SelectedText - c#

im working on a editor and i want to replace last comment after the intellisense appears .
further more heres the senario,
i got richtextbox(rtb) which served as the code-editor, and a hidden combobox(lb) which served as the intellisense . everytime i type words from richtextbox(rtb), sample i type "as", combobox will appear (like a intellisense) with keywords that starts from "as" .
all functions are working now except for after i select an item from combobox
sample string(combo box items): asd, asdf, asdfg .
then suppose to be i type as in richtextbox then i select 'asd' from combobox, then when i press enter the output would be:
as asd
instead of:
as (only)
further more heres my keyevents code:
void lb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
lb.Visible = false;
lb.Items.Clear();
}
if (e.KeyCode == Keys.Enter)
{
int start = 0, end = 0;
String line = rtb.Text.Substring(start, start - end);
int index = start;
string comment = line.Substring(index);
rtb.SelectedText = lb.SelectedText.ToString();
}
}
note: i just write:
rtb.SelectedText = comment + " " + lb.SelectedText.ToString();
for now to see some other function but that line was i the one i want to fix . also i even try:
rtb.SelectedText = comment - lb.SelectedText.ToString();
but it says Operator '-' cannot be applied to operands of type 'string' and 'string'
really thanks for the help in advance .
parameter:
if (token == "letterA" || token.StartsWith("Ab") || token.StartsWith("ab") || token.StartsWith("AB"))
{
int length = line.Length - (index - start);
string commentText = rtb.Text.Substring(index, length);
rtb.SelectionStart = index;
rtb.SelectionLength = length;
lb.Visible = true;
KeyWord keywordsHint = new KeyWord();
foreach (string str in keywordsHint.ab)
{
lb.Items.Add(str);
lb.SelectedIndex = lb.FindStringExact(str);
}
//token.Replace(lb.SelectedText,"");
}

I think this question/answer might be the problem:
ComboBox.SelectedText doesn't give me the SelectedText
Try using:
rbt.SelectedText = comment + " " + lb.Text
instead of SelectedText.

Related

Is it possible to pass textboxes as a parameter?

I'm attempting to pass the name of 2 textboxes into a method so that it edits the text in them. I have tried looking for examples online but can only find people attempting to pass textbox text through.
I've tried passing it in by declaring the text boxes in the method constructor.
MethodName(string text, tb_1, tb_2);
private void MethodName(string str, TextBox tb_name, TextBox tb_allergen)
{
string ingredientName = "";
string ingredientAllergen = "";
//code to change strings//
tb_name.Text = ingredientName;
tb_allergen.Text = ingredientAllergen;
}
After running the code I expect the text box text to be changed to the appropriate value, instead I get this error about the textboxes in the call.
"An unhandled exception of type 'System.InvalidCastException' occurred in mscorlib.dll
Additional information: Unable to cast object of type 'System.Windows.Forms.TextBox' to type 'System.IConvertible'"
Really sorry if there's an easy fix for this, but please point me in the right direction. Thanks in advance.
Real Code
ingredientDBAccess ingredientDBA = new ingredientDBAccess(db);
populateBoxesWithIngredientResults( ingredientDBA.getIngredientsFromID(Convert.ToInt32(tb_viewIngredient1)), tb_viewIngredient1, tb_viewAllergen1);
private void populateBoxesWithIngredientResults(List<ingredient> ingredientList, TextBox tb_name, TextBox tb_allergen)
{
string ingredientName = "";
string ingredientAllergen = "";
foreach (ingredient ingredient in ingredientList)
{
string name = Convert.ToString(ingredient.IngredientName);
ingredientName = name;
string allergen = "N/A";
switch (ingredient.AllergenID)
{
case 0:
allergen = "N/A";
break;
case 1:
allergen = "Nut";
break;
case 2:
allergen = "Gluten";
break;
case 3:
allergen = "Dairy";
break;
case 4:
allergen = "Egg";
break;
}
ingredientAllergen = allergen;
}
tb_name.Text = ingredientName;
tb_allergen.Text = ingredientAllergen;
}
Yes it is possible:
void MyMethod(string str, TextBox txt)
{
txt.Text = str + " some text from the method itself";
}
You may even return a TextBox:
TextBox MyFunc(string str)
{
TextBox txt = new TextBox();
txt.Text = str;
return txt;
}
You are trying to convert TextBox into Int32:
Convert.ToInt32(tb_viewIngredient1)
which is not parsable to Int32. You may convert it's text to int32 (if it has a numeric value and can be parsed) like:
int.Parse(tb_viewIngredient1.Text)
or
Conver.ToInt32(tb_viewIngredient1.Text)
The problem is the in two places
MethodName(string theStringVariable, tb_1, tb_2);
private void MethodName(string theStringVariable, TextBox tb_name, TextBox tb_allergen)
{
Convert.ToInt32(tb_viewIngredient1) will throw an exception because you're trying to convert a TextBox control to an int. Instead, try passing the Text property of the TextBox to the method:
Convert.ToInt32(tb_viewIngredient1.Text)
The problem is in (Convert.ToInt32(tb_viewIngredient1), you must convert it to:
(Convert.ToInt32(tb_viewIngredient1.Text)
I see three different options here. Any of these would be better even than the fixed code, depending on what your needs are. All of them address two points:
You can use a lookup table for the allergens rather than a switch. The resulting code is shorter/simpler and should run faster.
You loop through every item in ingredientList, but the textboxes will only ever keep data from the last item in the list. Either look at just that last item (no need for a loop), or use all of the items in the list (ie: create csv strings). The loop as it is is wasteful and complicates the code.
.
private void populateBoxesWithIngredientResults(IEnumerable<ingredient> ingredientList, TextBox tb_name, TextBox tb_allergen)
{
string nameDelimiter = "";
string allergenDelimiter = "";
string ingredients = "";
string allergens = "";
var allergenTable = {"N/A", "Nut", "Gluten", "Dairy", "Egg"};
foreach (ingredient ingredient in ingredientList)
{
//Is Convert.ToString() really needed here?
// I feel like ingredient.IngredientName is ALREADY A STRING
ingredients += delimiter + Convert.ToString(ingredient.IngredientName);
nameDelimiter = ",";
if (ingredient.AllergenID > 0 && ingredient.AllergenID < allergenTable.Length)
{
allergens += allergenDelimiter + allergenTable[ingredient.AllergenID];
allergenDelimiter = ",";
}
}
if (allergens == "") allergens = "N/A";
tb_name.Text = ingredients;
tb_allergen.Text = allergens;
}
or
private void populateBoxesWithIngredientResults(IEnumerable<ingredient> ingredientList, TextBox tb_name, TextBox tb_allergen)
{
tb_name.Text = string.Join(",", ingredientList.Select(i => i.IngredientName));
var allergenTable = {"N/A", "Nut", "Gluten", "Dairy", "Egg"};
var allergens = ingredientList.
Select(i => (i.AllergenID > 0 && i.AllergenID < allergenTable.Length)? allergenTable[i.AllergenID]):"").
Where(i => i.Length > 0);
var result = string.Join(",", allergens);
if (string.IsNullOrEmpty(result)) result = "N/A";
tb_allergen.Text = result;
}
or
private void populateBoxesWithIngredientResults(List<ingredient> ingredientList, TextBox tb_name, TextBox tb_allergen)
{
if (ingredientList.Length == 0)
{
tb_name.Text = "";
tb_allergen.Text = "";
}
var allergenTable = {"N/A", "Nut", "Gluten", "Dairy", "Egg"};
var ingredient = ingredientList[ingredientList.Count - 1];
tb_name.Text = ingredient.IngredientName;
if (ingredient.AllergenID >= 0 && ingredient.AllergenID < allergenTable.Length)
{
tb_allergen.Text = allergenTable[ingredient.AllergenID];
}
else
{
tb_allergen.Text = "N/A";
}
}

How to create a code from comboboxes using substring in c# visual studio?

So I'm doing a coursework in school about a music school and one thing I want to do is to be able to create a tuition code (made up of 6 characters) from 3 entered values.
So cbInstrument is a combobox, cbLevel is also a combobox and rb10Lessons/rb20Lesoons are radio buttons. When the code is running I want to be able to create a tuitionCode from these values as I choose them so that the tuition code would show up in a label of that same form as I choose the information.
For example; if in running form for instrument I click 'Cello', TuitionCode Shows up as CEL. Then after that if I click Level as 'Grade 1', TuitionCode shows up as CELB. And then if I choose 10 lessons then TuitionCode = CELB10.
Here is a sample of the code:
private void Tuition_Click(object sender, EventArgs e)
{
string code = "";
string codePart1 = code.Substring(0, 3);
string codePart2 = code.Substring(3, 1);
string codePart3 = code.Substring(4, 2);
if (cbInstrument.Text == "Cello")
{
codePart1 = "CEL";
}
else if (cbInstrument.Text == "Clarinet")
{
codePart1 = "CLA";
}
else if (cbInstrument.Text == "Double Bass")
{
codePart1 = "DBA";
}
if ((cbLevel.Text == "None") || (cbLevel.Text == "Grade 1") || (cbLevel.Text == "Grade 2"))
{
codePart2 = "B";
}
else if ((cbLevel.Text == "Grade 3") || (cbLevel.Text == "Grade 4") || (cbLevel.Text == "Grade 5"))
{
codePart2 = "I";
}
if (rb10Lessons.Checked)
{
codePart3 = "10";
}
else if (rb20Lessons.Checked)
{
codePart3 = "20";
}
lblTuitionCode.Text = code;
}
You are using the wrong function ... Subtring will return a substring within a string: for example : "123456".Substring(2,1)" will return "3"
What you need is simply to aggregate your string :
code = string.Format("{0}{1}{2}", codePart1, codePart2, codePart3);
that's it
The return value of Substring is its own string, not a reference to part of the string passed to it.
C# 6 has a feature called string interpolation which looks like this:
code = $"{codePart1}{codePart2}{codePart3}";
You could also use String.Format(...) if your VS version doesn't support C# 6 features.

Is there a way to use a variable in a catch block that was previously assigned in a try block?

So I've just been making a basic little calculator made up of buttons and a textbox(tbxSum).
The problem I'm having is that if an invalid sum is input I want my catch block to pick it up(which it does) and replace what's in the textbox with the most recent result in the calculator(which it doesn't).
So say I say:
3+3=6
My calculator will now put 6 in the textbox for the next sum.
So then say I did:
6//3
It's invalid which the calculator picks up, but I want the textbox value to return to 6 from the previous sum.
This is what I've tried:
var myButton = (Button)sender;
if (myButton.Content.ToString() == "=")
{
DataTable dt = new DataTable();
string s = tbxSum.Text;
string result = "";
if (s.Contains("("))
{
s = s.Replace("(", "*(");
}
try
{
var v = dt.Compute(s, "");
tbkSum.Text = s + "=" + v.ToString();
tbxSum.Text = v.ToString();
}
catch
{
MessageBox.Show("Invalid Sum");
tbxSum.Text = result;
}
}
I also have a textblock(tbkSum) which shows the previous sum so I thought maybe I could take everything in there to the right of the equals sign but I have no idea how to do that.
class Calculate(){
private boolean lastGoodValueSet = false;
private int lastGoodValue = 0;
void buttonFunction(){
if (myButton.Content.ToString() == "=")
{
//Your code
try
{
var v = dt.Compute(s, "");
tbkSum.Text = s + "=" + v.ToString();
lastGoodValue = v;
lastGoodValueSet = true;
}
catch
{
MessageBox.Show("Invalid Sum");
tbxSum.Text = result;
if (lastGoodValueSet)
tbxSum.Text = lastGoodValue;
}
}
}
}
This is an example set of code you could use, it's a simple value that you have to store to say if a good computation has been done and if so, at the point of error we want to go back to the computation. Hope that helps! You'll want to put some kind of message to the user, so they know there was an error though.
We have to do this, as at the point of the user pressing the equals button, the value has already changed inside tbkSum, we need it before the user has changed the value, so the best time to grab it is at the point when we update the tbkSum text value at a successful calculation
This is also assuming you do not create a new instance of the Calculate class each time you do your computation. Otherwise you'd need to store the number somewhere else
EDIT
The other way to fix this issue is to instead prevent the duplicate in the first place, I read from your other comments that you control what goes into the text box by buttons on the application. Assuming all buttons go through the same method of buttonFunction() then you could do:
private char[] buttonChars = {'/','*', '+'/*e.t.c*/}
void buttonFunction(){
string buttonPressedStr = myButton.Content.ToString();
char buttonPressed = buttonPressedStr[0];
int pos = Array.IndexOf(buttonChars , buttonPressed);
if (pos > -1)
{
if (tbxSum.Text.Length > 0){
char last = tbxSum.Text[tbxSum.Text.Length - 1];
pos = Array.IndexOf(buttonChars , last);
}
else
pos = 0;
if (pos > -1){
tbkSum.Text += buttonPressedStr;
}
}
There are cleaner ways to do this, but it's an example of how you could have prevented your issue in the first place. Some explanation:
buttonChars is an array of your different button types that would be appended to your text in the box, an example is +, -, and so on
First it checks if the button pressed was in your collection of specified buttonChars
If so, we have to check what the last thing added to the tbxSum was
If the last thing added to tbxSum was again found in the buttonChars array, we don't want to append a string
Otherwise, if the tbxSum was empty or had another character at the end, we can append our character
You can store the old value in a variable declard outside the try block and use this variable in your catch block again:
string oldSumValue = tbxSum.Text;
try
{
// your code
}
catch
{
tbxSum.Text = oldSumValue ;
MessageBox.Show("Invalid Sum");
}
Alternatively I've come up with this to prevent there being:
A)Duplicate of '*' or '/'
B)Sum starting with '*' or '/'
public MainWindow()
{
InitializeComponent();
if (tbxSum.Text == "")
{
btnDiv.IsEnabled = false;
btnMult.IsEnabled = false;
}
}
protected void btnSumClick(object sender, EventArgs e)
{
btnDiv.IsEnabled = true;
btnMult.IsEnabled = true;
var myButton = (Button)sender;
int pos = tbxSum.Text.Length;
if (pos > 0)
{
if ((tbxSum.Text[pos - 1] == '/' || tbxSum.Text[pos - 1] == '*') &&
(myButton.Content.ToString() == "/" || myButton.Content.ToString() == "*"))
{
int location = tbxSum.Text.Length - 1;
tbxSum.Text = tbxSum.Text.Remove(location, 1);
}
}
}

Finding specific value within a loop

I'm using an Enum within a ComboBox. I want it to allow editing, so that the user can type things in it. I converted the Enum to a string[] arrayItems while listItems is the length of the Enum list.
Now I want to check the users text input: If it isn't listed, it should show a message that the item is not listed there.
But for my code (below) it shows me a error multiple times:
// Converted enum to string[] before
for (int i = 0; i < listItems; i++)
{
if (comboBox1.Text != arrayItems[i])
{
message = string.Format("Sorry! " + comboBox1.Text + " not found.");
}
}
This shows error every time I start it as it iterates through each and every element in the list. I want that if this could check the whole Enum list and give the error once in case of wrong input.
You can change your loop as
bool ok = false;
for (int i = 0; i < listItems; i++)
{
if (comboBox1.Text == arrayItems[i])
{
ok=true;
break;
}
}
if(ok==false)
{
message = string.Format("Sorry! " + comboBox1.Text + " not found.");
}
if(arrayItrmd.Contains(combobox1.Text))
{
//logic if trur
}
You can use LINQ's All for this. As the name implies, it will only be true if all elements correspond to your query. It's basically the equivalent of !Any
if (arrayItrmd.All(item => item != comboBox1.Text))
{
message = string.Format("Sorry! " + comboBox1.Text + " not found.");
}
This means "If each element from arrayItrmd is not equal to comboBox1's text, assign the message."
You can ignore the use of a loop
if(tmpImageArray.FirstOrDefault(a => a == comboBox1.Text) == default(String))
{
message = comboBox1.Text + " not found";
}
else{
message = comboBox1.Text + " found";
}
I have solved this problem like this,
First my enum that I will bind to my combobox
public enum comboboxVals
{
one, two, three
}
Then set my combobox's datasource like this
comboBox1.DataSource = Enum.GetNames(typeof(comboboxVals));
and then implemented code in one of my combobox events to check if the value is valid like combobox Leave, Validating and Validated events..
private void comboBox1_Validating(object sender, CancelEventArgs e)
{
var cbx = sender as ComboBox;
if (!Enum.IsDefined(typeof(comboboxVals), cbx.Text))
{
MessageBox.Show(cbx.Text + " not in the list");
e.Cancel=true;
}
else
{
// Implement your logic here
}
}

How to check for end of string in textbox in c#

I am a noob, I am stuck on this code.
I am taking input from user in a textbox and saving it in a string. Then I want to run a loop until the string ends and I put if condition for different characters....
string que;
que = textBlock1.Text;
while (!que[i].Equals('\0'))
{
int res;
if (int.TryParse(que[i].ToString(), out res) || que[i].ToString() == "x" || que[i].ToString() == "/" || que[i].ToString() == "^")
{
f[j] = f[j] + que[i].ToString();
}
if (que[i].ToString() == "+" || que[i].ToString() == "-")
j++;
i++;
}
Can someone please guide me? What should I do??
Use:
textBlock1.Text.Lenght
That way you can know the length of the string.
Have you tried foreach(char c in que){ /*your code*/ } ?
If you want to just run through the loop until the end of the string, a simple condition like this should do:
int i = 0;
while (i < que.Length )
{
// Your code
}

Categories