Hi I wanna do override for all textBox But I wanna do TextChange method too
My TextChange Method is
private void TxtRozhaieKoleGharardad_OnTextChanged(object sender, TextChangedEventArgs e)
{
TryCatchBlock.ExecuteInTryCatch(() =>
{
if (TxtRozhaieKoleGharardad.Text != string.Empty)
{
int roz = Convert.ToInt32(TxtRozhaieKoleGharardad.Text);
PersianDate date = TxtTarikhShoro.SelectedDate.AddDays(roz);
TxtTarikhPayan.SelectedDate = date;
}
}, ref ResultMessageTryCatch);
}
and my override code is
class TextBox_JustNumbers : System.Windows.Controls.TextBox
{
protected override void OnTextChanged(TextChangedEventArgs e)
{
try
{
int caret = 0, lenghtText = 0;
if (this.CaretIndex == 0 || this.CaretIndex == this.Text.Length)
this.SelectionStart = this.Text.Length;
string value = this.Text.Replace(",", "");
decimal ul;
if (decimal.TryParse(value, out ul))
{
caret = this.CaretIndex;
lenghtText = this.Text.Length;
this.Text = string.Format("{0:#,#}", ul);
if (lenghtText + 1 == (this.Text.Length))
this.CaretIndex = caret + 1;
else
this.CaretIndex = caret;
}
}
catch
{
}
}
}
so when I run this code and change textBox Text Just do Override and don't go in TextChange Method How Can I fix It , I wanna do override behind orginal TextChange Method
I understand answer we must add
base.OnTextChanged(e);
after catch in override like this
...
if (lenghtText + 1 == (this.Text.Length))
this.CaretIndex = caret + 1;
else
this.CaretIndex = caret;
}
}
catch
{
}
base.OnTextChanged(e);
}
Related
I am new to C# and classes. I was testing on making a datagridview where the user can right click and a contextmenustrip pops. Now my question is the following.
I made my code to add the text to the textbox and increase the textbox if it is not empty.With help from this post.
private void TsmItem_Click(object sender, EventArgs e)
{
int rowindex = dgvResults.CurrentCell.RowIndex;
int columnindex = dgvResults.CurrentCell.ColumnIndex;
double resultText;
if (string.IsNullOrEmpty(Textbox.Text))
{
Textbox.Text = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
}
else
{
string selectedCell;
selectedCell = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
ResultText = Convert.ToDouble(Textbox.Text) + Convert.ToDouble(selectedCell);
Textbox.Text = Convert.ToString(ResultText);
}
}
Is there a way to only have this code only 1 time and call it every time I need it. So that I only have to change the textboxes.Text? Otherwise I need to copy and paste this code more than 10 times.
What I tried
private void TsmItem_Click(object sender, EventArgs e)
{
Textbox.Text = RightMouseClick(Textbox.Text);
}
private void RightMouseClick(string txtResult)
{
int rowindex = dgvResults.CurrentCell.RowIndex;
int columnindex = dgvResults.CurrentCell.ColumnIndex;
if (string.IsNullOrEmpty(txtResult))
{
txtResult = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
}
else
{
string selectedCell;
double resultText;
selectedCell = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
resultaat = Convert.ToDouble(txtResult) + Convert.ToDouble(selectedCell);
txtResult = Convert.ToString(resultText);
}
}
Fix
private string RightMouseClick(TextBox txtResult)
{
int rowindex = dgvResults.CurrentCell.RowIndex;
int columnindex = dgvResults.CurrentCell.ColumnIndex;
if (string.IsNullOrEmpty(txtResult.Text))
{
return txtResult.Text = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
}
else
{
string selectedCell;
double resultaat;
selectedCell = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
resultaat = Convert.ToDouble(txtResult.Text) + Convert.ToDouble(selectedCell);
return txtResult.Text = Convert.ToString(resultaat);
}
}
You can use the textbox as a parameter
private void RightMouseClick(TextBox txtBox)
{
int rowindex = dgvResults.CurrentCell.RowIndex;
int columnindex = dgvResults.CurrentCell.ColumnIndex;
if (string.IsNullOrEmpty(txtResult))
{
txtBox.Text = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
}
else
{
string selectedCell;
double resultText;
selectedCell = dgvResults.Rows[rowindex].Cells[columnindex].Value.ToString();
resultaat = Convert.ToDouble(txtBox.Text) + Convert.ToDouble(selectedCell);
txtBox.Text = Convert.ToString(resultText);
}
}
You should ensure that you also checking to make sure that the textbox isn't NULL
i'm new to C# (and programming at all) and i'm trying to write an 'XO' game along with ASP.NET
i'm getting a problem after the first player clicks a button.
turns doesn't switch and any click after the 1st does nothing. what is wrong with my code ?
public partial class GamePage : System.Web.UI.Page
{
Player player1 = new Player();
Player player2 = new Player();
int turn;
protected void Page_Load(object sender, EventArgs e)
{
this.turn = 0;
if (!IsPostBack)
{
Label1.Visible = true;
}
if (turn == 0)
{
Label1.Text = (Session["player1"] as Player).getname();
}
else
{
Label1.Text = (Session["player2"] as Player).getname();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["p1"] = player1;
Session["p2"] = player2;
player1.setsymbol("X");
player2.setsymbol("O");
if (Button1.Text == "")
{
if (turn == 0)
{
Button1.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button1.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Button2.Text == "")
{
if (turn == 0)
{
Button2.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button2.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button3_Click(object sender, EventArgs e)
{
if (Button3.Text == "")
{
if (turn == 0)
{
Button3.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button3.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
// this is an example - i have the same lines from button1 to 9
Everytime page renders, you set turn to 0 in Page_Load. Because Page_Load is executed upon every page load, you won't get any other value and this is probably the major issue here.
To properly support the lifetime of such variables that should keep value upon consecutive requests, wrap them in simple property:
public int turn
{
get
{
if ( Session["turn"] != null )
return (int)Session["turn"];
return 0; // default value if not set before
}
set
{
Session["turn"] = value;
}
}
This way everytime you refer to turn in your code, setting it to 0 or 1 or comparing the value to 0 or 1, you will refer to the same value, possibly stored during previous request(s).
this.turn=0; should be executed only when IsPostBack is false. Move this line inside if in your Page_Load.
When I type in the first textbox, it should run a conversion which appears in the second, and when I type in the second, it will appear in the first. However, when I type in the first textchanged event, it triggers the second, which disrupts entering in the first and vice versa. Is there a way I can disable firing the textchanged event when it is highlighted or something?
public void dB10_TextChanged(object sender, EventArgs e)
{
TextBox dB10 = sender as TextBox;
double dBV;
int i = dB10.Text.Trim().Length;
if (i > 0)
{
dBV = Convert.ToDouble(dB10.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
// Controls for if various radiobuttons were clicked
if (dBVRadio.Checked == true)
{
dBV = dBConverter.dBVToVolts(dBV);
voltage.Text = dBV.ToString();
}
else if (dBuRadio.Checked == true)
{
dBV = dBConverter.dBuToVolts(dBV);
voltage.Text = dBV.ToString();
}
}
public void voltage_TextChanged(object sender, EventArgs e)
{
TextBox voltage = sender as TextBox; //V >> dB10 (dBV/dBu)
int i = voltage.Text.Trim().Length;
double volts;
if (i > 0)
{
volts = Convert.ToDouble(voltage.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
if (dBVRadio.Checked == true)
{
dBuRadio.Checked = false;
volts = dBConverter.voltsTodBV(volts);
dB10.Text = volts.ToString();
}
else if (dBuRadio.Checked == true)
{
volts = dBConverter.voltsTodBu(volts);
dB10.Text = volts.ToString();
}
}
you can remove the handler of another textbox and then add it
public void dB10_TextChanged(object sender, EventArgs e)
{
voltage.TextChanged-= voltage_TextChanged;
TextBox dB10 = sender as TextBox;
double dBV;
int i = dB10.Text.Trim().Length;
if (i > 0)
{
dBV = Convert.ToDouble(dB10.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
// Controls for if various radiobuttons were clicked
if (dBVRadio.Checked == true)
{
dBV = dBConverter.dBVToVolts(dBV);
}
else if (dBuRadio.Checked == true)
{
dBV = dBConverter.dBuToVolts(dBV);
}
voltage.Text = dBV.ToString();
voltage.TextChanged+= voltage_TextChanged;
}
You can just use a bool variable:
bool escape = false;
public void dB10_TextChanged(object sender, EventArgs e)
{
if(escape)
return;
escape = true;
// your code
escape = false;
}
public void voltage_TextChanged(object sender, EventArgs e)
{
if(escape)
return;
escape = true;
// your code
escape = false;
}
I have created a code for my combobox, that can search addresses in a very large table on Sql Server with the help of stored procedure (i'm working with Entity framework). My stored procedure returns 10 hits and my code fills the combobox with search results. For doing this I'm using BackgroundWorker.
But here I'm now having big problems:
- although the combobox is filled with my search results, it always has the first item selected. Even if I type in only a letter, the whole text gets selected;
After that searching for the address doesn't work anymore. It searches only among these 10 results and I'm having no idea how to solve this. Here is my whole code, that causes me problems:
public String searchedItem = "";
public delegate void DelegateUpdateComboboxSelection(ComboBox myCombo,string value,int count);
BackgroundWorker m_bgworker = new BackgroundWorker();
static AutoResetEvent resetWorker = new AutoResetEvent(false);
m_bgworker.WorkerSupportsCancellation = true;
m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);
m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);
BindingList<spIskalnikNaslovi_Result1> m_addresses = new BindingList<SP_Result1>();
void m_bgworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
int count = (int)((object[])e.Result)[0];
string value = (string)((object[])e.Result)[1];
ComboBox myCombo = (ComboBox)((object[])e.Result)[2];
DelegateUpdateComboboxSelection ndelegate = new DelegateUpdateComboboxSelection(UpdateComboSelection);
if (this.InvokeRequired)
{
Invoke(ndelegate, new object[] {myCombo, value, count});
return;
}
else
{
UpdateComboSelection(myCombo, value, count);
return;
}
}
private void UpdateComboSelection(ComboBox myCombo, String value, int count)
{
myCombo = comboBox9;
myCombo.DataSource = m_addresses;
searchedItem = myCombo.Text;
if (count > 0)
{
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
}
public void FillComboboxBindingList(object sender, DoWorkEventArgs e)
{
if (m_bgworker.CancellationPending)
{
resetWorker.Set();
e.Cancel = true;
return;
}
else
{
string value = (String)((Object[])e.Argument)[0];
List<SP_Result1> result;
result = _vsebina.SP_searcher(value).ToList<SP_Result1>();
m_addresses = new BindingList<SP_Result1>();
foreach (SP_Result1 rez in result)
{
if (m_addresses.Contains(rez))
{
continue;
}
else
{
m_addresses.Add(rez);
}
}
foreach (SP_Result1 r in m_addresses.ToArray())
{
if (!result.Contains(r))
{
m_addresses.Remove(r);
}
}
e.Result = new object[] { rezultat.Count, vrednost, null };
return;
}
}
private void comboBox9_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back)
{
int searchStart = comboBox9.SelectionStart;
if (searchStart > 0)
{
searchStart--;
if (searchStart == 0)
{
comboBox9.Text = "";
}
else
{
comboBox9.Text = comboBox9.Text.Substring(0, searchStart + 1);
}
}
else
{
searchStart = 0;
}
e.Handled = true;
}
}
private void comboBox9_Enter(object sender, EventArgs e)
{
comboBox9.SelectionStart = 0;
comboBox9.SelectionLength = 0;
}
private void comboBox9_Click(object sender, EventArgs e)
{
comboBox9.Text = "";
}
private void comboBox9_KeyPress(object sender, KeyPressEventArgs e)
{
Search();
}
public void Search()
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
if (m_bgworker.IsBusy)
{
m_bgworker.CancelAsync();
m_bgworker = new BackgroundWorker();
m_bgworker.WorkerSupportsCancellation = true;
m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);
m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);
}
m_bgworker.RunWorkerAsync(new object[] { comboBox9.Text, comboBox9 });
}
}
Maybe can someone enlighten me, what I'm doing wrong. This is first time, that I'm using BackgroundWorker. I have no idea, how
to achieve "search as you type" with combobox in any other way, because my datatable with addresses is quite large (million records).
Thanks in advance for any kind of help or code example.
Vladimir
Edit 1:
Ok, here is my code, before I have used BackGroundWorker. It worked, but it searches very very slow (it can take up to 10 seconds):
private void comboBox9_TextChanged(object sender, EventArgs e)
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
FillCombobox(comboBox9.Text, comboBox9);
}
}
public void FillCombobox(string value, ComboBox myCombo)
{
List<spIskalnikNaslovi_Result1> result;
result = _vsebina.spIskalnikNaslovi1(value).ToList();
if (result.Count() > 0)
{
myCombo.DataSource = result;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
return;
}
Is there a way to speed this up without having backgroundworker?
make a button you will call searchbutton
and in click_event of this button call your search() method that run your backgroundworker
that fill the combobox
clear you key_press event of your combobox and it will work
the mistake is you key_press event that call every key stroke happening your search method
so retrieve it
You should get your items in a list, use that list to populate your combobox.
then set AutoCompleteMode property value to Suggest or Append or SuggestAppend and set AutoCompleteSoucre property value to ListItems.
For "Search as you Type", which is actually "Filter as you Type" more than search, you need to implement the OnKeyDown or KeyPressed event.
What you would do is take the search string, which is the current text at the time of the event, then filter the master list using that string. Normally one would use "Starts With" for the filtering, but you could also simply use "Contains". Then you live update the contents of the box with the results from the filter. This is accomplished by changing and refreshing the Datasource.
Here is my final solution without BackGroundWorker. It works quick with my large table, and is upgraded for using a stored procedure on SQL Server (if you use Entity Framework). I use Timer to make sure the user can find a value, that he is searching.
Here you can see the original solution, that I found on this site (thanks to Max Lambertini and algreat for the idea and working concept):
C# winforms combobox dynamic autocomplete
My solution:
private bool _canUpdate = true;
private bool _needUpdate = false;
List<spIskalnikNaslovi_Result1> dataFound;
private void comboBox12_TextChanged(object sender, EventArgs e)
{
if (_needUpdate)
{
if (_canUpdate)
{
_canUpdate = false;
refreshData();
}
else
{
restartTimer();
}
}
}
private void comboBox12_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back)
{
int searchStart = comboBox12.SelectionStart;
if (searchStart > 0)
{
searchStart--;
if (searchStart == 0)
{
comboBox12.Text = "";
}
else
{
comboBox12.Text = comboBox12.Text.Substring(0, searchStart + 1);
}
}
else
{
searchStart = 0;
}
e.Handled = true;
}
}
private void comboBox12_TextUpdate(object sender, EventArgs e)
{
_needUpdate = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
_canUpdate = true;
timer1.Stop();
refreshData();
}
private void refreshData()
{
if (comboBox12.Text.Length > 1)
{
FillCombobox(comboBox12.Text, comboBox12);
}
}
private void restartTimer()
{
timer1.Stop();
_canUpdate = false;
timer1.Start();
}
private void FillCombobox(string value, ComboBox myCombo)
{
dataFound = _vsebina.spIskalnikNaslovi1(value).ToList();
if (dataFound.Count() > 0)
{
myCombo.DataSource = dataFound;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
return;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
return;
}
}
I using this code for sum selected cells. Its work good but when user selecte cell where is letter is throws exceptions : ) how can i secure when in selectet cells is letters dont make sum
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
String filterStatus = DataGridViewAutoFilterColumnHeaderCell.GetFilterStatus(dataGridView1);
if (String.IsNullOrEmpty(filterStatus))
{
showAllLabel.Visible = false;
filterStatusLabel.Visible = false;
}
else
{
int result = -1;
Int32.TryParse(filterStatus, out result);
if (result != 0)
{
// it is a number
showAllLabel.Visible = true;
filterStatusLabel.Visible = true;
filterStatusLabel.Text = filterStatus;
}
else
{
// it can be a number yet won't help you with adding
}
}
}
this is my code
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
String filterStatus = DataGridViewAutoFilterColumnHeaderCell.GetFilterStatus(dataGridView1);
if (String.IsNullOrEmpty(filterStatus))
{
showAllLabel.Visible = false;
filterStatusLabel.Visible = false;
}
else
{
showAllLabel.Visible = true;
filterStatusLabel.Visible = true;
filterStatusLabel.Text = filterStatus;
}
}