I have a wpf form which contains a datagrid. I did put a button on my form to "Refresh" the datagrid. Steps I'm trying to get it to refresh:
I update the viewsource from my db:
SupportCaseViewSource.Source = SupportCaseManager.GetAllSupportCases();
I refresh the datagrid items:
SupportCaseDataGrid.Items.Refresh();
But nothing happens...no new data displayed!!
Has someone an idea how to do this?
Thanks
Beat
Rather than manually instructing your controls to refresh, you can implement INotifyPropertyChanged and call PropertyChanged with appropriate arguments. In your case this is probably
PropertyChanged(this, new PropertyChangedEventArgs("Source"));
It'll be whatever is bound to the SupportCaseDataGrid.ItemsSource.
Related
This is a side-related question to this other question:
BackgroundWorker in Silverlight ViewModel
I have a TabControl where I load many TabItems when the user selects menu options. I load this Tabs by binding the TabControl ItemsSource to an ObservableCollection. When I add a new TabItem to this Collection, it is shown perfectly.
The problem is I've realized that since user press a button until the tab is created (ViewModel and View creation takes a couple of seconds), the screen is freezed.
I've tried to set "IsBusy" before calling the "loadTab" but it doesn't shows up... I've tried almost everything with async calls but the UI thread is in use and it throws an exception when I create the new tab control.
Is there any trick I'm loosing??? Any ideas??? Thanks in advance.
have you seen this post?
http://www.dotnetspark.com/kb/3524-doesnt-your-girlfriend-deserves-more-time.aspx
It helps when you avoid heavy stuff in the load event and make Visible=true after you finish to load all your resources, so in that sense you avoid the user feeling tempted to click something that is not ready yet.
Not sure if it helps, but how about this idea?
public void DoStuff(Object values)
{
//your values object could be anything,
//they might even be some objects from your form
//as long as you dont modify them in the other thread
imgLoading.Visible=true;
var client = new Proxy();
client.OnWorkCompletedAsync +=client_OnCompleted() ;
client.Work(values);
}
void client_OnCompletedAsync(object sender, EventArgs e)
{
imgLoading.Visible=false;
//now you can update the UI with other stuff
}
Using the EventToCommand behaviour that comes with MVVM Light I am binding the SelectedItem of a ListBox to a RelayCommand on a ViewModel
All works great in my Windows Phone 7 app except that after navigating away from the View with the ListBox then back the SelectedItem is the same as before. Not what I want.
I tried reseting the selected index when navigating away but that causes the Command to trigger again.
Has anyone else solved this issue and how?
TIA
Patrick Long
I handle this by a simple check at the start of each handler. Assuming that you are only supporting the single selection of items you can check if there is an added item.
if (e.AddedItems.Count == 1)
{
// Your code here
}
(Where e is an instance of SelectionChangedEventArgs.)
If the selection has been removed the AddedItems list will be empty but the RemovedItems list will be populated instead.
Since you're using mvvm light can't you call the clear method in the ViewModelLocator for the specific view model?
I switched away from using the SelectionChanged event. Now I do it all with TapGestures. Downside of this is that TapGesture does not work with EventToCommand behaviour so I am trapping the Gesture event in the View and firing the Command that is bound to the DataContext of the Sender.
IMHO this is a lot neater than using SelctionChanged and mucking about with SelectedIndexes.
I have a WPF DataGrid with some data. You can add rows through a separate window. The DataContext is the same, a LINQ-to-SQL object. Binding is also the same, I bind the ItemsSource property to a table.
In the other window, when the user clicks on Save, I create a row programmatically and add it using InsertOnSubmit. After that I use the DataContext's SubmitChanges method.
My problem is that the DataGrid isn't updated. If I restart the application I can see the new row, so it's in the database, but I couldn't find a way to refresh the DataGrid.
So far I've tried to use UpdateTarget on the BindingExpression of the DataGrid, but it didn't help. I've also tried dataGrid.Items.Refresh() — same result. How can I fix this?
try datagrid.Items.Refresh() from here http://programmer.wrighton.org/2009/01/wpf-datagrid-items-refresh.html
The reason it's not updating is that LINQ-to-SQL doesn't implement INotifyCollectionChanged, so WPF has no way to tell that the ItemsSource has been updated. The least terrifying way to fix this, is to copy your LINQ-to-SQL results to an ObservableCollection - when you do the Insert, also add to the observable collection. Then you'll see the update.
I ran into same problem and found that best place for ObservableCollection is DataContext. It has some partial methods generated by designer that can be used to update collection. This code works pretty well:
partial class DataClassesDataContext
{
private ObservableCollection<Task> taskCollection;
public ReadOnlyObservableCollection<Task> TaskView { get; private set; }
partial void OnCreated()
{
taskCollection = new ObservableCollection<Task>(Tasks);
TaskView = new ReadOnlyObservableCollection<Task>(taskCollection);
}
partial void InsertTask(Task instance)
{
taskCollection.Add(instance);
this.ExecuteDynamicInsert(instance);
}
partial void DeleteTask(Task instance)
{
taskCollection.Remove(instance);
this.ExecuteDynamicDelete(instance);
}
}
The problem is that you need to refresh your LINQ-to-SQL DataContext. The DataContext's won't properly recognize the new row even after a submit changes. You need to dispose the DataContext you have and create a new one. In most cases DataContext should be used for one short operation and not as a long standing object.
If you have a case when you have to reload a grid in another window , you can simply close that window and invoke it again.
Or just invoke the search code again (usually the search button)> I have solved it in my case like this.
For some reason Items.Refresh() is not working for me.
What did work was to make my underlying collection inherit ObservableCollection and then call its Add method.
((ContactUIObjects)dgrdContacts.ItemsSource).Add(new ContactUIObject(o));
ContactUIObjects is just the grids underlying collection.
I'm writing an app that lets users browse through data, and I want to use the FireFox UI style: allow the user to open as many windows as they want, each with as many tabs as they want. I also want to try to do this using the Model-View-ViewModel pattern as much as possible.
Opening a new tab should be easy enough to handle in MVVM. Make an ObservableCollection of TabViewModel, bind that collection to the ItemsSource of a TabControl, and then opening a new tab is theoretically as easy as adding a new TabViewModel to the collection.
Here's the question that interests me: Is there a way to do the same thing for opening a new window? I.e., databind an ObservableCollection of WindowViewModel to the ItemsSource of... the Application's Windows collection?... so that when I add a new WindowViewModel to the observable collection, a new window automatically opens? And then tie that into app startup, so that instead of setting StartupUri, I just add the first WindowViewModel to the collection?
Since I can't actually databind Application.Windows, what would be the best way for the ViewModel layer to:
Add a new WindowViewModel and have a new Window appear automatically;
Remove the WindowViewModel and have its Window automatically close.
Remove the WindowViewModel from the collection if the user closes the window.
I could write my own object that watches an INotifyCollectionChanged and opens/closes windows in response to collection events, but I'm not sure whether that's the best way -- and if it is, I'm not sure of the best way to hook it into the application. Anyone have thoughts on the best way to go about this?
The point of MVVM is, that the ViewModel doesn't have to concern itself (in detail) with how the View will react to changes in the ViewModel.
One possibility would be a simple tracking algorithm in the View listening to the CollectionChanged event in the ViewModel, creating and destroying Windows on the go:
Dictionary<WindowModel, WindowView> _cache = new;
void WindowModelListChangedHandler(sender, args) {
switch(args.Action) {
case Add:
_cache[args.NewItem] = new WindowView(args.NewItem);
_cache[args.NewItem].Show();
break;
case Remove:
// ...
}
}
Which event fires when DataGrid's source is updating? I've tried DataContextChanged and SourceUpdated but it never worked out.
Actually I need a simple thing. I want, if there is a new row comes, scroll the GridView's scrollbar down to the bottom to see what it was.
I had the same problem and I manage it this way
DataGrid myGrid = new DataGrid();
CollectionView myCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(myGrid.Items);
((INotifyCollectionChanged)myCollectionView).CollectionChanged += new NotifyCollectionChangedEventHandler(DataGrid_CollectionChanged);
You then need to implement the logic in the event handler DataGrid_CollectionChanged.
Set NotifyOnTargetUpdated = true for the ItemsSource binding and handle TargetUpdated event. If you've multiple bindings, then look for DataTransferEventArgs Property to find out if the target is ItemsSource or not.
If you are trying to have the grid refresh when something is added to the database itself, that's not going to happen. I'm more familiar with WinForms than WPF but I'm assuming there is no magical way to keep a grid in sync with the database without writing some background process that continuously checks for database changes.
If you are updating the actual data source of the grid (ex. Collection) then that will update the grid.
For my part i've used SelectionChange notification which raise each event Del/Add/Edit/Select
It's work very well
private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Console.WriteLine("hi");
}