I need to flush my datagrid everytime when a treeviewitem is clicked. My code is given below.
private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
this.dataGrid1.Columns.Clear();
this.dataGrid1.ItemsSource= null;
String path =this.treeView1.SelectedItem;
if (!File.Exists(path))
MessageBox.Show("Not Found");
else
{
ob.provider(path);
// String data = #"C:\logs.xml";
string data = path;
objref.functionality(data);
this.dataGrid1.ItemsSource = objref.Result;
}
}
But everytime when I click a treeview item datagrid is not cleared-- it's appended with incoming data.
I used both dataGrid1.Columns.Clear() and dataGrid.ItemSource= null;
How can i do this??
If you are populating the DataGrid by using:
dataGrid.Items.Add(someObject);
Then you should be able to use:
dataGrid.Items.Clear();
To remove all the rows.
If you are binding to the ItemsSource like:
dataGrid.ItemsSource = someCollection;
Then you should be able to set the ItemsSource to null and it will remove all the rows.
EDIT:
Don't forget to refresh it:
dataGrid.Items.Refresh();
You may consider using ObservableCollection<> class rather than IEnumerable<>.
ObservableCollection<User> users = new ObservableCollection<User>();
dataGrid1.ItemsSource = users;
You can clear the datagrid by using the below code.
users.Clear();
I have tried several approaches and this was by far the best and most reliable one:
dataGrid.Columns.Clear();
dataGrid.Items.Clear();
dataGrid.Items.Refresh();
I had a public IEnumerable collection which is appended every time the function is called. So by overwriting it, I flushed the Data in my Datagrid.
I was able to clear my Data-Grid by setting the DataContext to null.
DataGrid.DataContext=null;
If it is bound an Itemsource, the simplest way is
dataGrid1.ItemSource = null;
Related
I have two windows wpf.
On the first window I see data from DataGrid, on the second window I delete object from database.
First window:
private void mnRemoveProduct_Click(object sender, RoutedEventArgs e)
{
RemoveProduct window = new RemoveProduct();
window.ShowDialog();
ShowWatchTable();
} // mnRemoveProduct_Click
Second window:
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
if (cmbNameOfWatch.SelectedIndex > 0)
{
var value =
(from watch in obj.Watch.Where(w => w.mark == cmbNameOfWatch.SelectedValue.ToString())
select new { watch.id }).ToArray().First();
Watch watchObj = obj.Watch.Find(value.id);
obj.Watch.Remove(watchObj);
obj.SaveChanges();
this.Close();
}
} // btnDelete_Click
and function ShowTable
public void ShowWatchTable()
{
obj.Watch.ToList();
dataGrid.ItemsSource =
from watch in obj.Watch.Local
select new
{
ID = watch.id,
Brand = watch.mark,
Typ = watch.TypeWatch.typeName,
Price = watch.price + " $".ToString(),
Quantity = watch.number,
Fabricator = watch.Fabricator.fName,
Country = watch.Fabricator.Country.countryName
};
}
When I delete value from database, I still see this value in DataGrid. Only when I close and open this form then I no longer see this object. When I add an element, the same logic is used. Datagrid is updated with the ShowTable function and I see the updated database. But when deleting it it does not work. Please help
From what I can see, you are deleting from obj.Watch using
obj.Watch.Remove(watchObj);
obj.SaveChanges();
but when refreshing your list, you are binding to obj.Watch.Local which I assume is a local cache of your datasource. I don't see where you are syncing this so you might want to sync that before binding or perform your operations on the local sync and ensure that it sends it's changes to the remote data source.
Well, my guess your data source is a query result, but i'm not pretty sure that it's observable(f.e. when I need to bind to collections, I use IObservableCollection to notify that collection changed).
Probably you can try to call dbGrid.Items.Refresh(); method when your primary views gets focus back
You just need to manually refresh your DataGrid.
Add this after your datasource is updated:
dataGrid.Items.Refresh();
You should make sure the collection backing the source of your data items implements INotifyCollectionChanged.
MSDN link to docs, also copied relevant section here.
Binding to Data
To bind the DataGrid to data, set the ItemsSource property to an IEnumerable implementation. Each row in the data grid is bound to an object in the data source, and each column in the data grid is bound to a property of the data object. In order for the DataGrid user interface to update automatically when items are added to or removed from the source data, the DataGrid must be bound to a collection that implements the INotifyCollectionChanged interface, such as an ObservableCollection. To automatically reflect property changes, the objects in the source collection must implement the INotifyPropertyChanged interface. For more information, see Data Binding (WPF).
So I've found a lot of questions similar to this tho nothing really solve my problem..
I have a combobx that is bounded by a datasource
cmbProduct.DataSource = this.masterDataSet.Product.Where(x => x.Location == getLocation).AsDataView();
cmbProduct.DisplayMember = "Product";
cmbProduct.ValueMember = "Product";
But whenever i update the source, the combobox items does not update automatically. I still need to close then reopen the form.
is there a method to refresh/reload/or update the combobox?
Solution 1
You can use an implementation of IBindingList as DataSource to view changes of data source in the bound list control (complex two-way data binding). The most suitable implementation is System.ComponentModel.BindingList<T>.
Then when you add items to the binding list, or remove item from it you will see changes immediately in the control.
Solution 2
But as a more simple solution with less changes for you, you can reset the databinding of your cmbProduct this way when you need; for example after a change, call RefreshBindings();:
public void RefreshBindings()
{
var list = put your updated list here;
this.cmbProduct.DataSource = null;
this.cmbProduct.DataSource = list;
this.cmbProduct.DisplayMember = "set the display member here";
this.cmbProduct.ValueMember = "set the value member here";
}
You could implement an event that fires whenever the DataSet changes. The event could reset the Datasource and rebind it.
Somewhere in your code:
yourDataController.DataChanged += OnDataChanged;
and the implementation
public void OnDataChanged(object sender, EventArgs e)
{
cmbProduct.Items.Clear();
cmbProduct.DataSource = this.masterDataSet.Product.Where(x => x.Location == getLocation).AsDataView();
cmbProduct.DisplayMember = "Product";
cmbProduct.ValueMember = "Product";
}
Edit: Of course you need to manually implement the event and cause it to fire every time your data changes.
I am developing an WPF application. It is having a DataGrid in it. I have assigned the ItemSource of my datagrid to an IEnumerable collection.
I have a Treeview in my window. When I click the element in the treeview it has to load the datagrid
private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
this.dataGrid1.ItemsSource = null;
this.dataGrid1.Visibility = Visibility.Visible;
this.dataGrid1.ItemsSource = objref.FinalValue;
// Where Objref.FinalValue is an IEnumerable collection.
grid_data = objref.FinalValue;
}
But the problem is everytime the selection is changed, the values in the datagrid is not overwrittenen but it is appended. I flushed the datagrid with dataGrid1.Columns.Clear() and dataGrid.ItemSource = null; Later I found out that the objref.FinalValue is appended. So even though I flushed the datagrid it displays the entire value..
So in the class which is having objref as instance I have used
private IEnumerable Result;
public IEnumerable FinalValue
{
get { return Result; }
set { Result = value; }
}
// Update Result with values so that it can be assigned to datagrid.
I need to overwrite not append. But the FinalValue has been appended every time. How can I resolve this issue?
Whenever you update the ItemsSource after the grid is rendered you have to call dataGrid1.Items.Refresh() to update it. After calling Refresh() the datagrid rows will reflect the new collection that is bound to it.
May I ask why does both comboboxes trigger each other such that both have same values?
Can't I share a single list and have 2 comboboxes with different selected text?
private void Form1_Load(object sender, EventArgs e)
{
BindingList<string> list = new BindingList<string>();
list.Add("A");
list.Add("B");
list.Add("C");
list.Add("D");
bind(cbo1, list);
bind(cbo2, list);
}
private void bind(ComboBox combobox, BindingList<string> list)
{
// commented lines are in actual code,
// but appears unimportant in this question
//combobox.DropDownStyle = ComboBoxStyle.DropDown;
//combobox.AutoCompleteSource = AutoCompleteSource.ListItems;
//combobox.AutoCompleteMode = AutoCompleteMode.Suggest;
combobox.DataSource = list;
//combobox.Focus();
//combobox.Text = string.Empty;
//combobox.SelectedText = string.Empty;
}
UPDATE:
Ok, now I found out the issue is that the DataSource is managed by some BindingContext and CurrencyManager to automatically synchronise the list. But I feel someone must know how to disable this behaviour.
I don't wish to use 2 different lists because I want to be able to modify this single list at runtime and have the changes be reflected on all ComboBoxes. Any method to achieve this would be greatly appreciated.
You can "solve" it like this:
// combobox.DataSource = list;
var curr = new BindingSource(list, null);
combobox.DataSource = curr;
There is a default BindingSource (Currencymanager) linked to each Form that was keeping the 2 cbx in sync. But I'm not sure what the exact rules are here. I'm not even sure if the above is a good idea or not.
For small lists I would just make separate copies.
You cannot use the same object as the datasource for 2 seperate combo boxes. You should have list1 and list2 defined and populate each combobox with each one. Using the same datasource means that a selection in one combobox is reflected in the other.
I am trying to add some data inside my DataGrid.
I added some columns with the designer. Now I want to add rows with data inside the DataGrid.
Here's my code so far:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var dataContext = new PurchaseOrderDataContext();
var purchaseOrderTable = dataContext.GetTable<PurchaseOrder>();
var query = from a in purchaseOrderTable
select a;
var purchaseOrders = query;
foreach (var purchaseOrder in purchaseOrders)
{
// I believe that this method is the right one, but what do I pass to it?
// dataGrid1.Items.Add(test);
}
}
All I want to know is: What kind of object do I need to use to add something in the DataGrid, and what kind of object do I need to pass to that last method? Also how do I add, let's say, text to a certain column of a row I added?
Thanks a lot!
In general, you would bind the ItemsSource of the grid to a collection that supports change notification (IObservableCollection is idea) and just add to the collection. If the collection supports change notification, the grid will automatically display the new row.
Try this:
dataGrid1.ItemsSource = query;