c# List view focus problem - c#

I have a listview which display the content from the database.I also have a refresh button in my form.Once the refresh button is clicked the listview is get updated once again.The problem is when the refresh button is clicked the already selected item in the listview is get removed from the focus.This is my code
private void btnRefresh_Click(object sender, EventArgs e)
{
//to refresh manually
this.Refresh();
listView1.Items.Clear();
/*btnEdit_Question.Enabled = true;
btnRepeat_Question.Enabled = true;
btnDelete_Question.Enabled = true;*/
GetData();
}
public void GetData()
{
try
{
now = DateTime.Now;
String time_date = now.ToString();
myConnection = new SqlConnection(connectString);
listView1.Items.Clear();
myConnection.Open();
String MyString1 = string.Format("SELECT " + data_variables.RES_TXT_STRING_COLUMN1 + "," + data_variables.RES_TXT_STRING_COLUMN2 + "," + data_variables.RES_TXT_STRING_COLUMN3 + "," + data_variables.RES_TXT_STRING_COLUMN4 + "," + data_variables.RES_TXT_STRING_COLUMN6 + " FROM " + data_variables.RES_TXT_STRING_QUESTION_TABLE);
com = myConnection.CreateCommand();
com.CommandText = MyString1;
dr = com.ExecuteReader();
ListViewItem itmX;
//Adding the Items To The Each Column
while (dr.Read())
{
itmX = new ListViewItem();
itmX.Text = dr.GetValue(0).ToString();
ListViewItem.ListViewSubItem aSubFooItem1 = new ListViewItem.ListViewSubItem(itmX, dr.GetValue(1).ToString()); //Creating subitems for the parent item
itmX.SubItems.Add(aSubFooItem1);
//Associating these subitems to the parent item
ListViewItem.ListViewSubItem aSubFooItem2 = new ListViewItem.ListViewSubItem(itmX, dr.GetValue(2).ToString()); //Creating subitems for the parent item
ListViewItem.ListViewSubItem aSubFooItem3 = new ListViewItem.ListViewSubItem(itmX, dr.GetValue(3).ToString()); //Creating subitems for the parent item
if (dr.GetValue(4).ToString() == "0")
{
aSubFooItem5 = new ListViewItem.ListViewSubItem(itmX, "No");
}
else
{
aSubFooItem5 = new ListViewItem.ListViewSubItem(itmX, "Yes");
}
if (dr.GetDateTime(2) < now && dr.GetDateTime(3) > now)
{
itmX.SubItems.Add(aSubFooItem2);
itmX.SubItems.Add(aSubFooItem3);
ListViewItem.ListViewSubItem aSubFooItem4 = new ListViewItem.ListViewSubItem(itmX, "In Progress");
itmX.SubItems.Add(aSubFooItem4);
itmX.SubItems.Add(aSubFooItem5);
}
else if (dr.GetDateTime(2) <= now)
{
itmX.SubItems.Add(aSubFooItem2);
itmX.SubItems.Add(aSubFooItem3);
ListViewItem.ListViewSubItem aSubFooItem4 = new ListViewItem.ListViewSubItem(itmX, "Expired");
itmX.SubItems.Add(aSubFooItem4);
itmX.SubItems.Add(aSubFooItem5);
}
else if (dr.GetDateTime(2) > now)
{
itmX.SubItems.Add(aSubFooItem2);
itmX.SubItems.Add(aSubFooItem3);
ListViewItem.ListViewSubItem aSubFooItem4 = new ListViewItem.ListViewSubItem(itmX, "Not Expired");
itmX.SubItems.Add(aSubFooItem4);
itmX.SubItems.Add(aSubFooItem5);
}
//add all the items ti listview
listView1.Items.Add(itmX);
//Adding colors
itmX.UseItemStyleForSubItems = false;
foreach (ListViewItem lvi in listView1.Items)
{
if (lvi.SubItems[4].Text=="Expired")
{
lvi.SubItems[4].BackColor = Color.Red;
}
else if (lvi.SubItems[4].Text == "Not Expired")
{
itmX.SubItems[4].BackColor = Color.Yellow;
}
else
{
itmX.SubItems[4].BackColor = Color.Green;
}
}
}
EventLog log = new EventLog(data_variables.RES_TXT_STRING_LOG_EVENT);
try
{
log.Source = data_variables.RES_TXT_STRING_LOG_SOURCE;
log.WriteEntry(data_variables.REX_TXT_STRING_MESSAGE_SUCCESSFUL, EventLogEntryType.Information);
}
if (listView_Selected_Index > -1)
{
//Keep the focus in the listview
this.listView1.Items[listView_Selected_Index].Focused = true;
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
now = DateTime.Now;
for (int i = 0; i < listView1.SelectedItems.Count; i++)
{
//Selecting the each values of the selected item from listview
listView_Selected_Index = listView1.SelectedIndices[i];
}
}
Can anyone help me how to remain the focus on the listview item even the refresh button is get clicked

You are removing original (some selected) items from the listview at the top of GetData().
You need to store somewhere what is selected before you read new data from database. Then after new data is displayed in listview you have to select items based on what was selected before data refresh.
//store selected items (id or sth else that identifies item)
GetData();
//restore selection (some of previously items may no longer exist)
In your code you only saving the last selected item not all of them.
for (int i = 0; i < listView1.SelectedItems.Count; i++)
{
//Selecting the each values of the selected item from listview
// here You are only saving last selected item
// instead of this do sth like
// selectedItems.Add(sth that identifies this item, not index)
listView_Selected_Index = listView1.SelectedIndices[i];
}
Also instead of doing it on every selectedIndexchanged You can do it only before data refresh unless you need it for some other reasons.

What you can do is, save the currently selected index of ListView1 in some temporary field and after calling GetData() method reset the selected index property of ListView1 by assigning value of temporary field to ListView1.SelectedIndex property
something like this:
private int _selectedIndex = -1;
private void btnRefresh_Click(object sender, EventArgs e)
{
_selectedIndex = listView1.SelectedIndex;
//to refresh manually
this.Refresh();
listView1.Items.Clear();
/*btnEdit_Question.Enabled = true;
btnRepeat_Question.Enabled = true;
btnDelete_Question.Enabled = true;*/
GetData();
listView1.SelectexIndex = _selectedIndex;
}

Related

show Listview column wise and and on button click show same listview in rowwise

I have a task to complete.. i must populate a list view from database and show in column wise and on a button click show it in a row wise... i just completed populating list view from database. now how do i display it it column wise and row wise... please help me...
This is the code i have tried to populate the database...
public partial class DtposMDIParentSystem : Form
{
List<object[]> result = new List<object[]>();
public DtposMDIParentSystem()
{
InitializeComponent();
//create the database connection
OleDbConnection aConnection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\AP_AE\Desktop\DTPOS_APP\DataBase\DtposDatabase.accdb;");
//create the command object and store the sql query
OleDbCommand aCommand = new OleDbCommand("SELECT * FROM Food", aConnection);
try
{
aConnection.Open();
//create the datareader object to connect to table
OleDbDataReader reader = aCommand.ExecuteReader();
int i = 0;
while (reader.Read())
{
result.Add(new Object[reader.FieldCount]);
reader.GetValues(result[i]);
}
reader.Close();
aConnection.Close();
}
catch (InvalidOperationException ex)
{
MessageBox.Show("Invalid Masseage = " + ex.Message);
}
}
private void cmdOlives_Click(object sender, EventArgs e)
{
if (result.Count > 0)
{
string temp = "";
for (int i = 0; i < result[1].Length; i++)
{
temp += result[1][i] + " ";
}
TableOrderListView.Items.Add(temp);
}
}
}
You can achieve something like that by switching between different view modes:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
listView1.View = View.Details;
listView1.HeaderStyle = ColumnHeaderStyle.None;
listView1.Columns[0].Width = listView1.ClientSize.Width - 25;
listView1.Height = 244;
}
else
{
listView1.View = View.List;
listView1.Columns[0].Width = 50;
listView1.Height = 44;
}
}
You need to add one Column for Details view to work!
Note that you will have to adapt the size of the Listview:
In Details mode it will need to be tall enough to show several items
In List mode it will have to to rather wide but must not be tall enough to show more than one item (plus the scrollbar)!
If instead you mean to switch rows and columns you will have to do that in your datasource!

uppercase items in listview C#

how can I change the character casing in my listview to uppercase? the items in listview should be in uppercase when I choose uppercase in combobox. I hope someone can help me with this. Thanks in advance.
private void Form1_Load(object sender, EventArgs e)
{
showlv("SELECT a.customer_name, a.address, b.product_name, b.price FROM tbl_customer AS a INNER JOIN tbl_transaction AS b WHERE a.customer_code = b.customer_code", lvcust);
}
private void showlv(string sql, ListView lv)
{
try
{
lvcust.View = View.Details;
lvcust.FullRowSelect = true;
lvcust.GridLines = true;
conn.Open();
MySqlDataAdapter sda = new MySqlDataAdapter(sql, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
conn.Close();
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow dr = dt.Rows[i];
ListViewItem lvitem = new ListViewItem(dr["customer_name"].ToString());
lvitem.SubItems.Add(dr["address"].ToString());
lvitem.SubItems.Add(dr["product_name"].ToString());
lvitem.SubItems.Add(dr["price"].ToString());
lvcust.Items.Add(lvitem);
}
string[] column = new string[4] { "Customer Name", "Address", "Product Name", "Price" };
for (int x = 0; x < column.Length ; x++)
{
lvcust.Columns.Add(column[x]);
}
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem.Equals("Ascend"))
{
lvcust.Sorting = SortOrder.Ascending;
}
else if (comboBox1.SelectedItem.Equals("Descend"))
{
lvcust.Sorting = SortOrder.Descending;
}
else if (comboBox1.SelectedItem.Equals("Uppercase"))
{
//code to uppercase items in listview
}
}
You would be better off adding your case changing method in the event handler for the checkbox to upload it.
So, you doubleclick the checkbox control, then you iterate through the items in the combobox, then on each iteration set the content of the item to itself, with a .ToUpper() at the end.
I'm assuming you want to uppercase the customer name only. The trick is to store the original value as the tag of the ListItem. That way you can change the Text back to the original (non-uppercase) value later if you wanted. So in your code, find the first line and add the second below:
ListViewItem lvitem = new ListViewItem(dr["customer_name"].ToString());
lvitem.Tag = dr["customer_name"].ToString();
Now that you have that, here's the for loop to convert it to upper case:
ListViewItemCollection items = lvcust.Items;
for(int i=0;i<items.Count;i++){
ListViewItem item = items.Item[i];
object tag = item.Tag;
if(tag is string){
item.Text = ((string)tag).ToUpper();
}
}
This was all done off the top of my head in a text editor so there may be a syntax issue here or there but the logic should be correct.

Dynamically created RadioButtons in a Gridview losing state

Background Info:
For various reasons I'm having to dynamically create a RadioButtonList in a column of my GridView.
The grid presents the user with a bunch of data on which they have to leave a comment and make a decision on one of 3 radio options:
Naturally, there are a number of rows on the grid. And the way this is to work is the user makes comments and decisions on all the items before saving to the database.
This screen is to be used multiple times, so the radio buttons have to reflect the value that's stored in the database.
The Problem:
Everything works apart from one thing: the radio buttons are always being reset to their initial state (value = 1) because the grid and the controls are being re-created on postback.
Code:
Here's the working code, some of it redacted/edited...
protected void TheGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
[...]
foreach (DataControlFieldCell dc in e.Row.Cells)
{
switch (dc.ContainingField.ToString())
{
[...]
case (_ColReview):
int status = int.Parse(dc.Text);
if (status == 0)
{
dc.Text = "Not sent for review";
}
else
{
var comment = new TextBox();
comment.ID = "ReviewCommentTextBox";
comment.CssClass = "form-control";
comment.Width = 290;
dc.Controls.Add(comment);
var radioButtons = new RadioButtonList();
var rb = new ListItem();
if (status == 2) rb.Selected = true;
rb.Value = "2";
rb.Text = "Yes, Add to Watch List";
radioButtons.Items.Add(rb);
rb = new ListItem();
if (status == 3) rb.Selected = true;
rb.Value = "3";
rb.Text = "No, do not add to Watch List";
radioButtons.Items.Add(rb);
rb = new ListItem();
//initial value in database is 1, hence this will be initially selected
if (status == 1) rb.Selected = true;
rb.Value = "1";
rb.Text = "Skip: no decision";
radioButtons.ID = "RowRadioButtonList";
radioButtons.Items.Add(rb);
dc.Controls.Add(radioButtons);
}
break;
}
}
}
}
protected void BulkupdateLinkButton_Click(object sender, EventArgs e)
{
foreach(GridViewRow gvr in TheGridView.Rows)
{
[...]
int radioItemValue = 0;
foreach (DataControlFieldCell dc in gvr.Cells)
{
string cellName = dc.ContainingField.ToString();
string cellText = dc.Text;
switch(cellName)
{
[...]
case (_ColReview):
TextBox tb = (TextBox)gvr.FindControl("ReviewCommentTextBox");
comment = tb.Text;
RadioButtonList rbl = (RadioButtonList)gvr.FindControl("RowRadioButtonList");
foreach(ListItem li in rbl.Items)
{
//Issue arrives here: selected item is reset on postback, value is always 1
if (li.Selected)
{
radioItemValue = ToolBox.ConvertToInt(li.Value);
}
}
break;
}
}
if (!string.IsNullOrEmpty(comment) && (radioItemValue > 0))
{
if (radioItemValue != 1) // 1 = pending/skip
{
//code to add update the record and save the comment
[...]
}
}
}
}
Idea on solution
Now I can get around this by using a HiddenField in each row and setting up some JavaScript/JQuery to record the chosen RadioButton but I can't help but think I'm missing a trick here? Can anyone offer up a better/neater solution?
To restore a RadioButtonList to the saved selected value I believe you need to set the RadioButtonList.SelectedIndex property of the list, not the Selected property of the ListItem

Inserting Data in to db while going forward in asp.net survey web application

Here is my code which populates the question from db table based on their object type (droprdown,checkbox,radioutton..)
if (str.Trim().ToLower() == "dropdown box")
{
string[] strArr = strOptions.Split('|');
DropDownList ddl = new DropDownList();
ddl.ID = "ddl";
ddl.CssClass = "CheckBox";
ddl.Width = Unit.Pixel(100);
// ddl.Items.Add(new ListItem("test", "test"));
if (strArr.Count() > 0)
{
foreach (string s in strArr)
{
ddl.Items.Add(new ListItem(s, s));
}
}
else
{
ddl = new DropDownList();
ddl.ID = "ddlContent1";
ddl.Width = Unit.Pixel(150);
plc.Controls.Add(ddl);
}
plc.Controls.Add(ddl);
}
if (str.Trim().ToLower() == "checkbox list")
{
string[] strArr = strOptions.Split('|');
if (strArr.Count() > 0)
{
foreach (string s in strArr)
{
CheckBox chk = new CheckBox();
chk.ID = s;
chk.Text = s;
chk.CssClass = "CheckBox";
if (strFooterOptions == "If all of the above are checked, please SUBMIT. [Click here to Submit]")
chk.Attributes.Add("onclick", "checkAllCheckBox()");
plc.Controls.Add(chk);
plc.Controls.Add(new LiteralControl("<br />"));
}
}
and my prev and next button , when you hit next it shows you another questions in another sections.
protected void btnNext_Click(object sender, EventArgs e)
{
// int section = 1;
section = section + 1;
btnPrev.Enabled = true;
FillSection();
}
protected void btnPrev_Click(object sender, EventArgs e)
{
section = section - 1;
FillSection();
}
How can i create a method to insert responses to database when i hit next?.
Any idea Appreciate
Thanks
It depends on how you store your survey options I think. I made a similiar thing, storing all options in same row in database. First created a cookie to store what survey is taken (ex: all city pages have surveys and London is taken). Then I created a function to do the db stuff,
IF NOT EXISTS (Select * from your_survey_table where column=cookievalue)
INSERT INTO your_survey_table (your_columns_here) VALUES (#your_values)
ELSE
UPDATE your_survey_table SET option2=#your_value

Display same message twice and thrice using listView

I am working in a listview where I am trying to add role in it.
I have validation method that prevent the listview to have duplicate role.
The problem is it throws same message twice when I select another list item of listView
and it throws same message thrice when i select the scrollbar of list View. I think
the using the listView.BeginEdit() in wrong way. Please ! help me to sort this problem
Code :
private void AddDefaultRoles()
{
ListViewItem lvi = new ListViewItem("Reader");
listViewRoles.Items.Add(lvi);
lvi = new ListViewItem("Writer");
listViewRoles.Items.Add(lvi);
lvi = new ListViewItem("Administrator");
listViewRoles.Items.Add(lvi);
lvi = new ListViewItem("Delete");
listViewRoles.Items.Add(lvi);
lvi = new ListViewItem("Admin");
listViewRoles.Items.Add(lvi);
lvi = new ListViewItem("Contributor");
listViewRoles.Items.Add(lvi);
lvi = new ListViewItem("Designer");
listViewRoles.Items.Add(lvi);
}
private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text))
textBox1.Text = "New Role";
ListViewItem lvi = new ListViewItem(textBox1.Text);
listViewRoles.Items.Add(lvi);
lvi.Selected = true;
lvi.BeginEdit();
}
private void listViewRoles_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
ListViewItem lvi = listViewRoles.Items[e.Item];
string newName = e.Label;
if (newName == null)
newName = lvi.Text;
if (!ValidateRoleName(newName, e.Item))
{
lvi.BeginEdit();
return;
}
}
private void listViewRoles_BeforeLabelEdit(object sender, LabelEditEventArgs e)
{
}
private bool ValidateRoleName(string name, int itemIndex)
{
const bool validName = true;
if ((string.IsNullOrEmpty(name.Trim()))) //empty name
{
MessageBox.Show(this, "empty role name", "Rename failed");
return !validName;
}
if (NameExists(name, itemIndex)) //name already exists
{
MessageBox.Show(this, "already exists", "Rename failed");
return !validName;
}
return validName;
}
private bool NameExists(string newName, int itemIndex)
{
const bool nameExists = true;
for (int i = 0; i < listViewRoles.Items.Count; ++i)
{
if (itemIndex == i)
continue;
if (string.Compare(listViewRoles.Items[i].Text.TrimEnd(), newName.TrimEnd(), true) == 0)
{
return nameExists;
}
}
return !nameExists;
}
Edit (from misplaced answer):
private void listViewRoles_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
ListViewItem lvi = listViewRoles.Items[e.Item];
string newName = e.Label;
if (newName == null)
newName = lvi.Text;
if (_checkRoleName)
{
if (!ValidateRoleName(newName, e.Item))
{
_checkRoleName = false;
lvi.BeginEdit();
return;
}
}
else
{
_checkRoleName = true;
lvi.BeginEdit();
}
}
this.listViewRoles.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listViewRoles_AfterLabelEdit);
this.listViewRoles.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listViewRoles_BeforeLabelEdit);
When I try the above code it show message box once when i changed the selected index but still when i click the scroll bar, it will called the AfterLabelEdit event so the message called twice. I need a proper solution such that if the added listviewitem is already exists in listview, the added listViewItem persist in edit mode until its name is changed or unique.
You have your call in the wrong event
Use the 'AfterLabelEdit' event.
MSDN AfterLabelEdit

Categories

Resources