I have a ListView whose items are fetched from an Api call. Then I add another item , send it to api to add it. I want to update the existing list with the value I just added.
I am doing something like this:-
itemList = dataAgent.GetItemList(some params);
cAdapter = new ItemsListAdapter(this, itemList);
lvItems.Visibility = ViewStates.Visible;
lvItems.Adapter = cAdapter;
SetListViewHeightBasedOnChildren(lvItems);
}
btnItemComment.Click += btnItemComment_Click;
void btnItemComment_Click(object sender, EventArgs e)
{
string itemsText = editComments.Text.ToString().Trim();
if(string.IsNullOrEmpty(itemsText))
{
CreateAndShowAlert(this, "", "Please enter a text");
}
else
{
var status = dataAgent.PostItem (Some more params);
if(status)
{
cAdapter.NotifyDataSetChanged();
}
}
}
But the ListView does not get refreshed. Is there anything else I need to do? Any help would be appreciated
Set adapter again and then add NotifyDataSetChanged:-
cAdapter = new ItemsListAdapter(this, itemList);
cAdapter.NotifyDataSetChanged();
Related
I am working on a Windows application where I get an input from a TextBox and add it to the DataGridView when user clicks on a Button (Add).
My problem is that when I add the text for the first time, it works fine and its added to the grid.
When I add new text, it's not added to the DataGridView. Once the Form is closed and reopened with the same object then I am able to see it.
Code:
private void btnAddInput_Click(object sender, EventArgs e)
{
if (Data == null)
Data = new List<Inputs>();
if (!string.IsNullOrWhiteSpace(txtInput.Text))
{
Data.Insert(Data.Count, new Inputs()
{
Name = txtInput.Text,
Value = string.Empty
});
}
else
{
MessageBox.Show("Please enter parameter value", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
txtInput.Text = "";
gridViewInputs.DataSource = Data;
}
I am not sure what is causing the record not to be added to grid on second add button click.
You could set the DataGridView.DataSource to null before setting a new one.
This would cause the DataGridView to refresh its content with the new data in the source List<Inputs>:
the underlying DataGridViewDataConnection is reset only when the DataSource reference is different from the current or is set to null.
Note that when you reset the DataSource, the RowsRemoved event is raised multiple times (once for each row removed).
I suggest to change the List to a BindingList, because any change to the List will be reflected automatically and because it will allow to remove rows from the DataGridView if/when required: using a List<T> as DataSource will not allow to remove a row.
BindingList<Inputs> InputData = new BindingList<Inputs>();
You can always set the AllowUserToDeleteRows and AllowUserToAddRows properties to false if you don't want your Users to tamper with the grid content.
For example:
public class Inputs
{
public string Name { get; set; }
public string Value { get; set; }
}
internal BindingList<Inputs> InputData = new BindingList<Inputs>();
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = InputData;
}
private void btnAddInput_Click(object sender, EventArgs e)
{
string textValue = txtInput.Text.Trim();
if (!string.IsNullOrEmpty(textValue))
{
InputData.Add(new Inputs() {
Name = textValue,
Value = "[Whatever this is]"
});
txtInput.Text = "";
}
else
{
MessageBox.Show("Not a valid value");
}
}
If you want to keep using a List<T>, add the code required to reset the DataGridView.DataSource:
private void btnAddInput_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textValue))
{
//(...)
dataGridView1.DataSource = null;
dataGridView1.DataSource = InputData;
txtInput.Text = "";
}
//(...)
I am fairly new to C#. I have a MainWindow which contains a ListView (lvStores), furthermore, I have a button that will open another window (NewStoreWindow). The NewStoreWindow contains 2 textboxes and an OK button. When I write something in the textboxes and press OK, the window is is rightfully closing and adding to my ListView. However, when I try to add a new item to the ListView, after adding the first, it will just overwrite it. Or actually, it will remove it, and then it will add the next one. I believe it has to do with my ObservableCollection. I have tried to put them in my public MainWindow() but then the code wouldn't execute. Furthermore, I have tried to use List instead of ObservableCollection.
Snippet of MainWindow code
private void cmdNewStore_Click(object sender, RoutedEventArgs e)
{
if (m_blnBusy)
{
return;
}
// Open NewStoreWindow in a new window
NewStoreWindow newStore = new NewStoreWindow();
newStore.ShowDialog();
ObservableCollection<AddListViewItem> lvColumnList = new ObservableCollection<AddListViewItem>();
ObservableCollection<AddListViewItem> items = (ObservableCollection<AddListViewItem>)lvStores.ItemsSource;
lvStores.ItemsSource = lvColumnList;
switch (SLvCol)
{
// If CSV is NOT loaded on start up and listview is then empty
case false:
// If no items exist in listview
if (items == null)
{
// Add item from textbox from NewStoreWindow
lvColumnList.Add(new AddListViewItem() {sID = SNewStoreTbid, sName = SNewStoreTbName});
lvStores.ItemsSource = lvColumnList;
// Refresh listview
lvStores.Items.Refresh();
}
else // If items exists
{
if (items != null)
{
bool itemAlreadyAdded = false; // use for boolean checking
foreach (AddListViewItem item in items) // loop through all items in listview
{
//Do some work with the item
MessageBox.Show(item.sID);
if (item.sID == SNewStoreTbid) // Check if new item already exists
{
itemAlreadyAdded = true;
break;
}
if (itemAlreadyAdded) // Show messagebox if it exists
{
MessageBox.Show("ID needs to be unique, please respecify!", "Duplicate ID",
MessageBoxButton.OK, MessageBoxImage.Error);
}
else // if it does not exist, create it from the textbox values
{
lvColumnList.Add(
new AddListViewItem() {sID = SNewStoreTbid, sName = SNewStoreTbName});
lvStores.ItemsSource = lvColumnList;
// refresh listview
//ICollectionView view = CollectionViewSource.GetDefaultView((List<AddListViewItem>)lvStores.ItemsSource);
//view.Refresh();
lvStores.Items.Refresh();
}
}
}
}
break;
.....
}
// Bind textbox values from NewStoreWindow
public class AddListViewItem
{
public string sID { get; set; }
public string sName { get; set; }
}
AddListViewItem item = new AddListViewItem
{
sID = SNewStoreTbid, //SNewStoreTbid,
sName = SNewStoreTbName //SNewStoreTbName
};
I'm having some issues with posting back a RowCommand from a GridView. Not sure if my logic is correct so if somebody could point out where I am going wrong that would be great.
It seems there are lot of similar problems but none of the solutions have a default set of results in the gridview then rebinded with search results like this scenario.
The problem is when the RowCommand is fired I have the wrong result. On default load the button works correctly but if I search for customers and then use the RowCommand, the page posts back and rebinds the grid with the default customers always sending me to the wrong customer.
Page Load: Fill GridView with logged in users default clients
Search Box: Search companies entire client list and repopulate gridview
RowCommand: Send users to the customer
Postback:
if(!IsPostBack)
{
//Check if user logged in
User A_User = new User();
if(!A_User.Check_Logged_In())
{
if(A_User.Should_Redirect(System.IO.Path.GetFileName(Request.PhysicalPath)))
{
//Redirect user to login page
Response.Redirect(A_User.Login_Page());
}
}
//Modify nav buttons
HtmlGenericControl nav = (HtmlGenericControl)this.Page.Master.FindControl("UserPanel").FindControl("li_nav_address_book");
nav.Attributes["class"] = "active";
//Load logged in users customers
BindGrid(false);
}else
{
//Check for request
if(Request.Params["__EVENTTARGET"] != null)
{
//Check for search string
if(Request.Params["__EVENTTARGET"].ToString().Contains("SearchCustomers"))
{
//Load customers by search results
BindGrid(true);
}
//else
//{
// if(Request.Params["__EVENTTARGET"].ToString().Contains("btn2"))
// {
// Console.WriteLine("SENDER: ", "btn2 RowCommand");
// BindGrid(true);
// }
//}
}
}
Search Button:
protected void btn_Search_Click(object sender, EventArgs e)
{
BindGrid(true);
}
Grid Binding:
private void BindGrid(bool Search)
{
if(!Search)
{
//Load customers by rep ID
Contacts Contact_Manager = new Contacts();
gvCustomers.DataSource = null;
DataSet dsCustomers = Contact_Manager.Get_Customers_By_UserID((int)Session["User_ID"]);
DataTable tblCustomers = dsCustomers.Tables[0];
gvCustomers.DataSource = tblCustomers;
gvCustomers.DataBind();
}
else
{
//Load customers by search terms
Contacts Contact_Manager = new Contacts();
//Search by replacing spaces to do a rainbow database search as whole text instead of tags
DataSet dsCustomers = Contact_Manager.Get_Customers_By_Tags(tb_GetContacts.Text.Replace(" ", ""));
DataTable tblCustomers = dsCustomers.Tables[0];
gvCustomers.DataSource = null;
gvCustomers.DataSource = tblCustomers;
gvCustomers.DataBind();
}
}
RowCommand:
protected void gvCustomers_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if(e.CommandName == "Customer_Detail")
{
int Customer_ID = Convert.ToInt32(e.CommandArgument);
Response.Redirect("~/Customer/" + Customer_ID);
}
}
I have the following button click event:
private void button_GetTrucks_Click(object sender, EventArgs e)
{
if (textBox_CompanyCode.Text.Length != 3)
{
_errorProvider.SetError(button_GetTrucks, "Invalid company code.");
return;
}
textBox_CompanyCode.Enabled = false;
button_GetTrucks.Enabled = false;
_corporationId = GetCorporationId(textBox_CompanyCode.Text);
if(_corporationId == Guid.Empty)
{
_errorProvider.SetError(button_GetTrucks, "Could not find company.");
return;
}
dataGridView1.DataSource = null;
_soureItemCollection = null;
textBox_CorporationId.Text = _corporationId.ToString();
var query = GetTrucks(_corporationId);
_soureItemCollection = new ObservableCollection<Truck>(query);
dataGridView1.DataSource = _soureItemCollection;
MakeDataGridViewPerty();
button_GetTrucks.Enabled = true;
textBox_CompanyCode.Enabled = true;
}
public static List<Truck> GetTrucks(Guid corporationId)
{
return (from trk in Entity.Trucks
where trk.CorporationId == corporationId
orderby trk.TruckNumber
select trk).ToList();
}
When I get the data initially by clicking the button, it works fine. If the data has changed, due to another program changing the data and I click this button again to refresh the data, it stays the same and does not display the changed data.
If I restart the application, click the button, the new data is displayed correctly.
So, it takes me restarting the application to reload the data.
Why is the button click not reloading the data?
I have seen where you have to add in a databind to get it to rebind
dataGridView1.DataSource = _soureItemCollection;
dataGridView1.Databind();
Before this call: var query = GetTrucks(_corporationId); place this one first:
Entity.Refresh(RefreshMode.OverwriteCurrentValues,Entity.Trucks);
At my user-control I populate listbox with collection and want save data in viewstate\controlstate for further autopostback using.
protected void btFind_Click(object sender, EventArgs e)
{
var accounts = new AccountWrapper[2];
accounts[0] = new AccountWrapper { Id = 1, Name = "1" };
accounts[1] = new AccountWrapper { Id = 2, Name = "2" };
lbUsers.DataSource = accounts;
lbUsers.DataBind();
ViewState["data"] = accounts;
}
ListBox is populated at button click. When I save accounts to ViewState listBox is empty, when not it displays collection good. What's reasonn of this behaviour?
After your button is being clicked, PostBack occurs and ListBox loses it's state.
void lbUsers_DataBinding(object sender, EventArgs e)
{
if (this.IsPostBack &&)
{
AccountWrapper[] accounts = this.ViewState["data"] as AccountWrapper[];
if (accounts!= null)
{
lbUsers.DataSource = accounts;
lbUsers.DataBind();
}
}
}
(don't forget to subscribe to DataBinding event of your ListBox in markup)
Also I recommend you to encapsulate your access to ViewState:
private AccountWrapper[] Accounts
{
get { return this.ViewState["data"] as AccountWrapper[]; }
set { this.ViewState["data"] = value;
}