Change Session/ViewState on buttonclick - c#-4.0

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

Related

C# Win Form - Main thread not responding when using background worker

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!

Unity Vuforia Google VR - Can't make onPointerEnter to GameObject change material for itself

I have two 3d buttons in my scene and when I gaze into any of the buttons it will invoke OnPointerEnter callback and saving the object the pointer gazed to.
Upon pressing Fire1 on the Gamepad I apply materials taken from Resources folder.
My problem started when I gazed into the second button, and pressing Fire1 button will awkwardly changed both buttons at the same time.
This is the script I attached to both of the buttons
using UnityEngine;
using UnityEngine.EventSystems;
using Vuforia;
using System.Collections;
public class TriggerMethods : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
Material _mat;
GameObject targetObject;
Renderer rend;
int i = 0;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Fire1"))
TukarMat();
}
public void OnPointerEnter(PointerEventData eventData)
{
targetObject = ExecuteEvents.GetEventHandler<IPointerEnterHandler>(eventData.pointerEnter);
}
public void OnPointerExit(PointerEventData eventData)
{
targetObject = null;
}
public void TukarMat()
{
Debug.Log("Value i = " + i);
if (i == 0)
{
ApplyTexture(i);
i++;
}
else if (i == 1)
{
ApplyTexture(i);
i++;
}
else if (i == 2)
{
ApplyTexture(i);
i = 0;
}
}
void ApplyTexture(int i)
{
rend = targetObject.GetComponent<Renderer>();
rend.enabled = true;
switch (i)
{
case 0:
_mat = Resources.Load("Balut", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
case 1:
_mat = Resources.Load("Khasiat", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
case 2:
_mat = Resources.Load("Alma", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
default:
break;
}
}
I sensed some logic error and tried making another class to only manage object the pointer gazed to but I was getting more confused.
Hope getting some helps
Thank you
TukarMat() is beeing called on both buttons when you press Fire1. If targetObject is really becoming null this should give an error on first button since it's trying to get component from a null object. Else, it'll change both as you said. Make sure OnPointerExit is beeing called.
Also, it seems you are changing the shared material.
The documentation suggests:
Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.
It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.
So, try changing the material property instead of sharedMaterial since it'll change the material for that object only.

How to stop onItemSelected() from firing off multiple times after a selection of an item was made?

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;
}
}

Pivot Control ManipulationCompleted

ManipulationCompleted event doesn't work in WP8 SDK. What would be an alternative way to solve this problem?
Including dectecting swipe right or left, or choose other pivot item by clicking on the pivot header.
You can use SelectedIndex to identified selected pivot page. For instance, you can use as:
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch (((Pivot)sender).SelectedIndex)
{
case 0:
ApplicationBar = ((ApplicationBar)Resources["AppBar1"]);
break;
case 1:
ApplicationBar = ((ApplicationBar)Resources["AppBar2"]);
break;
case 2:
ApplicationBar = ((ApplicationBar)Resources["AppBar3"]);
break;
case 3:
ApplicationBar = ((ApplicationBar)Resources["AppBar4"]);
break;
}
}
Hope this help

Highlight the selected cell in a DataGridView?

In my code below, I'm showing a context menu when the user right-clicks on a cell in my DataGridView. I'd also like the cell that the user right-clicks on to change background color so that they can see the cell they've "right-click selected". Is there a way to add something to my code below so that this occurs?
private void dataGridView2_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu m = new ContextMenu();
MenuItem mnuCopy = new MenuItem("Copy");
mnuCopy.Click += new EventHandler(mnuCopy_Click);
m.MenuItems.Add(mnuCopy);
int currentMouseOverRow = dataGridView2.HitTest(e.X, e.Y).RowIndex;
m.Show(dataGridView2, new Point(e.X, e.Y));
}
}
So obviously you've hacked into my workstation and have seen some of the stuff I've worked on recently. I exaggerate a bit because I didn't do exactly what you're trying to do but with a little bit of tweaking I was able to.
I would modify your MouseClick event to get the DGV's CurrentCell. Once you have it, set the CurrentCell's Style property with the SelectionBackColor you want. Something like this:
// ...
DataGridView.HitTestInfo hti = dataGridView2.HitTest(e.X, e.Y);
if (hti.Type == DataGridViewHitTestType.Cell) {
dataGridView2.CurrentCell = dataGridView2.Rows[hti.RowIndex].Cells[hti.ColumnIndex];
dataGridView2.CurrentCell.Style = new DataGridViewCellStyle { SelectionBackColor = System.Drawing.Color.Yellow};
}
//...
The above is a bit 'air code-y' (in other words I haven't attempted to merge it with your code and run it) but I hope you get the idea. Notice that I check through the hit test that a cell was clicked; if you don't do this and the user does not click a cell you might have some problems.
Now there's the problem that this code will change the SelectionBackColor for the all the cells you right click. That's easy to restore this property in the DGV's CellLeave event:
private void dgvBatches_CellLeave(object sender, DataGridViewCellEventArgs e) {
dataGridView2.CurrentCell.Style = new DataGridViewCellStyle { SelectionBackColor = System.Drawing.SystemColors.Highlight };
}
I'll have to remember this visual affect; thanks for asking the question.

Resources