I catch the event down, but I need to save the clicked buttons.
for example a way to get modifiers + e.key
This is my code:
protected override void OnKeyDown(KeyEventArgs e)
{
//base.OnKeyDown(e);
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.E)
{
MessageBox.Show(test.ToString());
}
}
I tried to combine two keys like
Key test = Key.Ctrl | e.Key ;
but it always give wrong results , for exampl Ctrl + E result in due to the above code to J
I want to save it, and I want to make those shortcuts general in all UserControls.
Try like this using KeyGesture:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.Key ==Key.E && e.KeyboardDevice.Modifiers==ModifierKeys.Control)
{
KeyGesture keyGesture = new KeyGesture(e.Key, e.KeyboardDevice.Modifiers);
if (keyGesture.Matches(null, e))
{
//This should match!
}
}
}
ok as I use silverlight4 , I will use
Tuple<ModifierKeys, Key>
it work great and its performance is great
Related
I have a datagridview which is being populated by a DataTable through DataSource and i am using a backgroundworker for formatting of cells (back color and forecolor of cells) in datagridview.
BackgroundWorker bw = new BackgroundWorker();
private void Frm_Find_Load(object sender, EventArgs e)
{
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
CheckForValidValues();
}
public bool CheckForValidValues()
{
dgv.Invoke((MethodInvoker)delegate()
{
for (int i = 0; i < Dt.Rows.Count; i++)
{
if (Dt.Rows[0]["Name"].ToString() == Value)
{
dgv.Rows[i].Cells["Name"].Style.BackColor = Color.FromArgb(255, 192, 192);
}
else
{
dgv.Rows[i].Cells["Name"].Style.BackColor = Color.White;
}
progressBar1.Invoke((MethodInvoker)(() => progressBar1.Value++));
}
});
this.Invoke((MethodInvoker)delegate()
{
BtnShow.Enabled = true;
dgv.Enabled = true;
});
}
private void btnSave_Click(object sender, EventArgs e)
{
if (bw.IsBusy == false)
{
progressBar1.Visible = true;
progressBar1.Value = 0;
BtnShow.Enabled = false;
dgv.Enabled = false;
progressBar1.Maximum = dgv.Rows.Count;
bw.RunWorkerAsync();
}
}
while the whole process goes down the DataGridView remains Enabled=false so that user cant change any values in datagridview.
There is usually 15,000 rows in the datagridview and that many rows to format, this takes time that is why I use a backgroundworker for it and it works perfectly fine BUT when the user tries to press the enabled false datagridview couple of times, the main thread becomes unresponsive and the progressbar freezes.
Can anyone guide me how to deal with it?
You are running the whole code using Invoke. It means you are switching to UI thread and the code is running in UI thread. Since the code is a time-consuming for loop, then it's blocking UI thread.
Instead of using a BackgroundWorker, to format cells, it's better to use CellFormatting event:
private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
//If this is header cell or new row, do nothing
if (e.RowIndex < 0 || e.ColumnIndex < 0 || e.RowIndex == dgv.NewRowIndex)
return;
//If formatting your desired column, perform validation
if (e.ColumnIndex == dgv.Columns["Name"].Index)
{
// Perform validation and change cell back color here.
}
}
Maybe try to disable the Button when it get clicked until the job done?.
Lets say your Button name is Button1,
when the user click on the Enabled false data grid view, use Button.enabled=false, then when the job is done use Button.enabled=true
hope that helps!
I have a text box in my app. In this app, I am creating my own Undo/Redo functionality because the text in my textbox represents something much larger in memory, and I need to track these textbox changes to be able to undo/redo the whole project properly.
As part of that, I need to capture -- and handle -- many common keyboard scenarios on my own. Yes, I know this is going to be painful.
My major hurdle at the moment is the fact that the textbox intercepts (and even hides) the "usual" keys like Ctrl+X, Ctrl+V, Ctrl+Z and Ctrl+Y. It does this so that it can implement its own undo-redo, but I don't need the built-in undo/redo stuff. I would like to completely disable these keys in my UWP app.
I know that you can do this in winforms, but UWP appears to be a different beast.
private async void MyTextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
var ctrl = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
// Handle special keys!!
if (ctrl && e.Key == Windows.System.VirtualKey.F)
{
Find_Click(null, null);
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.R)
{
Replace_Click(null, null);
e.Handled = true;
}
...
else if (ctrl && e.Key == Windows.System.VirtualKey.Z)
{
// THIS DOES NOT FIRE
Undo();
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.Y)
{
// THIS DOES NOT FIRE
Redo();
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.X)
{
// THIS DOES NOT FIRE
CaptureUndo("");
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.V)
{
// THIS FIRES, BUT THE PASTE HAS ALREADY HAPPENED
// SO e.Handled IS USELESS
string s=GetClipboardText();
CaptureUndo(s);
e.Handled = true;
}
}
I would really appreciate a nudge in the right direction.
I have a textbox for search (that is, textBox1)
A user, for example, enters "aba" in textBox1.
"abandon" puts in datagridiew1.
The user clicks on datagriview1:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
richTextBox_MWE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if ("richTextBox_MWE.Text like '%" + textBox1.Text + "%'")
{
label5.BackColor = Color.Green;
}
}
I want if "abandon" is such as "aba" in textBox1, label5.BackColor becomes Green.
Simple way is use the textBox1(where actually filter content going to change) change event
if(!String.IsNullOrEmpty(richTextBox_MWE.Text) && richTextBox_MWE.Text.Trim().Contains(textBox1.Text.Trim()))
{
label5.BackColor = Color.Green;
}
You want to use some kind of mix of C# and sql :) You can use the String.Contains method to achieve what you want.
if(richTextBox_MWE.Text != null
&& richTextBox_MWE.Text.Contains(textBox1.Text.Trim())
{
...
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
richTextBox_MWE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if (!String.IsNullOrEmpty(richTextBox_MWE.Text) && !String.IsNullOrEmpty(textBox1.Text) && richTextBox_MWE.Text.Contains(textBox1.Text.Trim()))
{
label5.BackColor = Color.Green;
}
}
Here the contains will accept the value to be searched.
See snippet from my code. The txtProductCode is a text box that user is filling the product_code for searching in the list view.
string tmpProductCode = txtProductCode.Text.Trim();
string tmpProductCodePattern = "^" + Regex.Escape(tmpProductCode).Replace("%", ".*") + "$";
In my loop of product_code(s) the prodCode will contain the product_code value for each loop.
productCodeClause = false;
if (tmpProductCode.Equals(""))
{
productCodeClause = true;
}
else
{
if (Regex.IsMatch(prodCode, tmpProductCodePattern))
{
productCodeClause = true;
}
}
I hope this will be helpful.
I've seen another similar thread, but I wasn't able to resolve my issue with the given answers.
EXPLANATION OF MY GOALS:
I have 4 spinners, each has its own ArrayList of strings assigned to it via an adapter. All of these arrays contain the same values at the beginning.
I want to remove the selected value (eg. "item" in spinner1) from all the other spinners (remove "item" from spinner2, 3 and 4) when it is selected.
PROBLEM:
When I select an item for the first two or three times from different spinners (the number of selections needed to reproduce the problem varies) the onItemSelected() method gets called multiple times (the number of callings is greater than the number of actual -user- selections made).
QUESTION:
How to prevent the calling of onItemSelected(); at unnecessary times. I want it to be called only when the actual user makes a selection in one of the spinners and only call it once when that does happen.
If you want to try to help me out and you need more code / images of the problem on the device itself, please, say so.
Here is my whole onItemSelected() method:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (inCorrection == false)
{
s1 = spinner1.getSelectedItemPosition();
s2 = spinner2.getSelectedItemPosition();
s3 = spinner3.getSelectedItemPosition();
s4 = spinner4.getSelectedItemPosition();
testcount++;
switch(parent.getId())
{
case R.id.v1_q1_s1:
if((position != AdapterView.INVALID_POSITION) && (spinner1.getSelectedItem().toString() != "Default---"))
{
findLists(myList2, myList3, myList4, spinner1.getSelectedItem().toString());
if(returnChecks(0) != "Default---")
{
myList2.add(returnChecks(0));
myList3.add(returnChecks(0));
myList4.add(returnChecks(0));
}
addChecks(0, (spinner1.getSelectedItem().toString()));
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList2.add(returnChecks(0));
myList3.add(returnChecks(0));
myList4.add(returnChecks(0));
addChecks(0, (spinner1.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
case R.id.v1_q1_s2:
if((position != AdapterView.INVALID_POSITION) && (spinner2.getSelectedItem().toString() != "Default---"))
{
findLists(myList1, myList3, myList4, spinner2.getSelectedItem().toString());
if(returnChecks(1) != "Default---")
{
myList1.add(returnChecks(1));
myList3.add(returnChecks(1));
myList4.add(returnChecks(1));
}
addChecks(1, (spinner2.getSelectedItem().toString()));
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList1.add(returnChecks(1));
myList3.add(returnChecks(1));
myList4.add(returnChecks(1));
addChecks(1, (spinner2.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
case R.id.v1_q1_s3:
if((position != AdapterView.INVALID_POSITION) && (spinner3.getSelectedItem().toString() != "Default---"))
{
findLists(myList2, myList1, myList4, spinner3.getSelectedItem().toString());
if(returnChecks(2) != "Default---")
{
myList2.add(returnChecks(2));
myList1.add(returnChecks(2));
myList4.add(returnChecks(2));
Toast.makeText(Vprasalnik1.this, "before: "+returnChecks(2), Toast.LENGTH_LONG).show();
}
addChecks(2, (spinner3.getSelectedItem().toString()));
Toast.makeText(Vprasalnik1.this, "after: "+returnChecks(2), Toast.LENGTH_LONG).show();
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList2.add(returnChecks(2));
myList1.add(returnChecks(2));
myList4.add(returnChecks(2));
addChecks(2, (spinner3.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
case R.id.v1_q1_s4:
if((position != AdapterView.INVALID_POSITION) && (spinner4.getSelectedItem().toString() != "Default---"))
{
findLists(myList2, myList3, myList1, spinner4.getSelectedItem().toString());
if(returnChecks(3) != "Default---")
{
myList2.add(returnChecks(3));
myList3.add(returnChecks(3));
myList1.add(returnChecks(3));
}
addChecks(3, (spinner4.getSelectedItem().toString()));
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList2.add(returnChecks(3));
myList3.add(returnChecks(3));
myList1.add(returnChecks(3));
addChecks(3, (spinner4.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
}
correctSelection();
}
}
At the end of the above code there is a function I call named correctSelection();, that corrects the selection of all spinners, because it doesn't work correctly otherwise - it looks like this:
void correctSelection()
{
inCorrection = true;
spinner1.setSelection(myList1.lastIndexOf(returnChecks(0)));
spinner2.setSelection(myList2.lastIndexOf(returnChecks(1)));
spinner3.setSelection(myList3.lastIndexOf(returnChecks(2)));
spinner4.setSelection(myList4.lastIndexOf(returnChecks(3)));
inCorrection = false;
}
/*it sets the position of all spinners to the last "saved"
(current) item selected, so it corrects the possible index offset that occurs otherwise
(returnChecks(); returns the last item selected from an array in a string format)
PS: To avoid the calling of onItemSelected() in case of programmatically setting the selection
of spinners, I've input a boolean flag (variable "inCorrection"), which is set to false before the
selections are made by "the application" and then set back to false when the code gets run.
*/
To prevent onItemSelected() from being called when you set up the spinner, you can do it like this:
spinner.setOnItemSelectedListener(null);
adapter.notifyDatasetChanged();
spinner.setSelection(0, false);
spinner.setOnItemSelectedListener(onItemSelectedListener);
Explanation:
The framework fires the onItemSelected event when a change in the selection has occurred. It detects a change by registering the current selected position and the previous selected position (mSelectedPostion and mOldSelectedPosition).
When you call notifyDatasetChanged the framework performs various checks to see if the previous selection can be found, so onItemSelected may or may not be called when the spinner is laid out.
By calling setSelection(0, false) these positions are set to 0, possibly detecting a change, but since onItemSelectedListener is null, onItemSelected wont be fired. Position 0 is selected because I guess the "Default---" value is the first position in the list. You can choose another position if you like.
When the spinner is later laid out there is no change, so onItemSelected wont be fired here either.
Note that this has been established by debugging on API level 19 (Android 4.4 KitKat). I don't know if it works on other versions, and I haven't been able to find anything in the documentation to support it.
You can stop the spinner from firing prior to the user making a selection via the optional animation field in the setSelection method. Be sure to order your code this way:
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, yourList);
spinner.setAdapter(spinnerAdapter);
spinner.setSelection(0, false); //stops spinner from firing prior to user selection
as explained by user1801374 , I made the fix for my case. Just make sure before and after selection index remains same in order to not to invoke the onItemSelected again.
private int spinnerIndex = 0;
spinner.setSelection(spinnerIndex, false);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{ public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
// Your code here
//I was detaching and reattaching one fragment which was calling the onItemSelected multiple times, recursively.
spinnerIndex = i;
spinner.setSelection(spinnerIndex, false);
return;
}
public void onNothingSelected(AdapterView<?> adapterView) {
// Your code here
return;
}
}
me again,
I have a current page containing a usercontrol which lists buildings.
Here is a screenshot: http://i40.tinypic.com/2eusoyt.png
Now, my mentor asked me to build a button which allows the user the make the page show the properties in 2 columns.
How did I try this?
I tried putting the following in my Page_load:
if (ViewState["numberOfColumns"] != null)
{
numberOfColumns= Int32.Parse(ViewState["numberOfColumns"].ToString());
}
else
{
ViewState["numberOfColumns"] = 1;
numberOfColumns= 1;
}
Then behind the button view I put this code:
protected void btnView_Click(object sender, EventArgs e)
{
switch(numberOfColumns)
{
case 1:
numberOfColumns= 2;
ViewState["numberOfColumns"] = numberOfColumns;
break;
case 2:
numberOfColumns= 1;
ViewState["numberOfColumns"] = numberOfColumns;
break;
}
}
But as I guessed this method needs one postback to set the sessionvariable, and another one to execute the pageload with the latest value.
I know there should be "a proper way" of doing this, but I can't find it.
Any direct you guys could point me would be greatly appreciated.
Thanks in advance, Christophe
Okay,
This is how I did it.
The method building the output of the user control was called directly after the snippet above. It's called "GetProperties()".
So the problem was/is that according to the page cycle, .net first executes the Page_Load, and as last the control events.
So what I did was put the call to getProperties() for the first time (when IsPostback = false) in an if. So when you visit the page once, it will load the method, and after that no longer.
So, then I put the methodcall in my button, because when you click the button IsPostback = true.
This worked. Snippets below:
protected void Page_Load(object sender, EventArgs e)
{
//some generic stuff
if (!IsPostBack)
{
ViewState["kolommen"] = 1;
AantalKolommen = 1;
GetProperties(_tkth, _categorie, _verkochtverhuurd);
}
}
And behind the button I did the following:
protected void btnView_Click(object sender, EventArgs e)
{
switch (Int32.Parse(ViewState["kolommen"].ToString()))
{
case 1:
AantalKolommen = 2;
ViewState["kolommen"] = 2;
break;
case 2:
AantalKolommen = 1;
ViewState["kolommen"] = 1;
break;
}
GetProperties(_tkth, _categorie, _verkochtverhuurd);
}
This works like a charm. Altho, I'd still like to know if this