Hi I have a datagrid that is populated via an ICollectionView
public ICollectionView MemberView { get; private set; }
Members = new ObservableCollection<Member>(_memberService.LoadCustomers());
MemberView = CollectionViewSource.GetDefaultView(Members);
All works fine until I update a status on a member to 'Live' from another viewmodel.
I then try and search on this recordset but the record never turns up until I restart the application.
I am using MVVMLight and the messenger to trigger the reload (Not really important here as the messagebox confirms its running correctly)
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ReloadClients")
{
Members = _memberService.LoadCustomers();
MemberView.Refresh();
RunFilter();
MessageBox.Show("Clients Reloaded");
}
}
Am I going about this the correct way? Any help will be very much appreciated.
Thanks Scott
Related
I'm writing a program for managing a tool inventory and have run into a problem when I have the users mark a tool as 'fixed'.
The program should work as follows:
Using TIView, TIViewModel, TIModel:
Employee checks tool out.
Tool happens to get damaged during use.
Employee return's the tool marking it as damaged and reporting the problem.
The tool is marked as returned and locked from being check out until fixed.
Using VPRView, VPRViewModel, and VPRModel:
An inspector goes into a data grid showing all tools with problems.
The inspector corrects the problem, marks the tool as fixed, then submits the data.
The program updates the SQLite database with the inspectors ID number, their solution, marks the problem as fixed and logs the date/time of completion.
THE PROBLEM STEP:
8. The program then runs the PopulateToolInventory method from the TIViewModel to update the inventory list so that the tool is no longer locked.
Summarized:
When the inspector marks the tool as fixed the database is updated using the VPRView, VPRViewModel, and VPRModel. The method to pull the data for the tool inventory is found in the TIViewModel. How do I get the application to execute the 'PopulateToolInventory' method from the VPRViewModel after uploading the data to the database via the VPRViewModel?
Code Sample:
VPRViewModel:
public void SubmitSolution()
{
VPRModel vprm = new VPRModel();
vprm.SubmitProblemSolution(ProblemSolved, ProblemSolution, InspectorID, SelectedReport[0].ToString());
ProblemReports = vprm.RetrieveProblemReports();
InspectorID = null;
ProblemSolution = null;
ProblemSolved = false;
MessageBox.Show("Solution successfully recorded!", "Success!", MessageBoxButton.OK);
// This is where I would want to call the method from the TIViewModel to update the data grid on the TIView.
}
TIViewModel:
private DataTable _toolInventory;
public DataTable ToolInventory
{
get { return _toolInventory; }
set
{
_toolInventory = value;
NotifyOfPropertyChange(() => ToolInventory);
}
}
public void PopulateToolInventory()
{
TIModel tim = new TIModel();
ToolInventory = tim.RetrieveToolInventory();
}
ShellViewModel:
class ShellViewModel : Conductor<object>
{
public void Open_ToolInventory()
{
ActivateItem(new TIViewModel());
}
public void ViewProblemReport()
{
WindowManager wm = new WindowManager();
VPRViewModel vprvm = new VPRViewModel();
wm.ShowDialog(vprvm);
}
}
FYI: I'm using Caliburn.Micro if this helps with any solution.
Hopefully this is enough information. If not, just ask for what you need! Also, please don't eat my code alive. I'm self taught and know that I'm far from a professional developer but this is a passion of mine and I'm really enjoying it. Constructive criticism is appreciated, just please don't make me feel stupid.
Using Ed's idea in the question comments I did the following.
class ShellViewModel : Conductor<object>
{
public void Open_ToolInventory()
{
ActivateItem(new TIViewModel());
}
public void ViewProblemReport()
{
WindowManager wm = new WindowManager();
VPRViewModel vprvm = new VPRViewModel();
wm.ShowDialog(vprvm);
}
}
Was changed to:
class ShellViewModel : Conductor<object>
{
TIViewModel tivm = new TIViewModel();
VPRViewModel vprvm = new VPRViewModel();
public void OpenToolInventory()
{
ActivateItem(tivm);
}
public void ViewProblemReport()
{
WindowManager wm = new WindowManager();
wm.ShowDialog(vprvm);
tivm.PopulateToolInventory();
}
}
This runs the targeted method after the dialog is closed updating the tool inventory to reflect all the solved problems at once. You're the best, Ed!
I'm new in the forum. Sorry for my English... It's not very well.
Please, I read the article:
How to Perform Multiple "Pings" in Parallel using C#
Please, someone give me a help and to explain how can I populate a WPF Datagrid to monitoring a list of IP's ?
I'm build a class:
...
public class ServerMonitor
{
public string ID { set; get; }
public string Timeout { set; get; }
public string IP { set; get; }
public string TTL { set; get; }
}
...
In main method I got it show data in datagridview.
MonitorPing.PingAddressesAsync(new List<IPAddress>() {
IPAddress.Parse ("XXX.XXX.XXX.XXX"),
IPAddress.Parse ("XXX.XXX.XXX.XXX"),
IPAddress.Parse ("XXX.XXX.XXX.XXX"),
IPAddress.Parse ("XXX.XXX.XXX.XXX")
}, delegate (Task<List<PingReply>> tpr)
{
var lr = tpr.Result;
foreach (var pr in lr)
{
//This correct
Dispatcher.BeginInvoke(DispatcherPriority.Normal,(ThreadStart)(() => dataGrid.Items.Add(new ServerMonitor { ID = pr.Buffer.ToString(), Timeout = pr.Status.ToString(), IP = pr.Address.ToString(), TTL = pr.RoundtripTime.ToString() })));
}
});
}
At this point, it's all right.
But how do I get the data to be updated in real time? I use a while, use a System.Timer...
Tks and sorry for anything!
To display a list of items in the DataGrid with values that are automatically updated in the UI you will need to bind your DataGrid to an ObservableCollection of objects which implement INotifyPropertyChanged interface.
The code which performs the actual pinging would reside in your ViewModel which will also contain the ObservableCollection. That code would periodically iterate through the objects in that ObservableCollection and update the desired public Properties of each object with ping results and these values will be automatically updated in the DataGrid because they implement the INotifyPropertyChanged interface.
I have a Windows Phone 8 Pivot application which contains the auto generated MainViewModel Binding mechanism.
I have changed the MainViewModel class to suit my needs and changed the MainPage.xaml markup so that it binds to the correct properties.
All good.
Now - I have a class which calls a Web Service and a call-back method which fires when data is received:
private void GetSigns_Completed(object sender, OpenReadCompletedEventArgs e)
{
using (var sr = new StreamReader(e.Result))
{
var data = sr.ReadToEnd();
var result = JsonConvert.DeserializeObject<SignViewModel>(data);
}
}
As you can see, I am not returning or populating anything with the result object as I do not know how to do so. The MainViewModel's properties have private setters:
public ObservableCollection<SignViewModel> Signs { get; private set; }
public ObservableCollection<TweetsViewModel> Tweets { get; private set; }
Each of these objects have a NotifyPropertyChange event.
So how do I populate the Signs and Tweets objects and make the whole binding work automatically when retrieving data from a Web Service? How do I make the UI/Mainpage.xaml communicate with the Web Service Class and the MainViewModel class?
To solve the issue, I simply changed the setters to public for Signs and Tweets. Once this was in place, the NotifyPropertyChange worked it's magic and automatically bound to the View. Magic! I wonder why Microsoft Developers made the setters private .....
I'm a little stuck on an issue with WPF datagrids, and once again my google foo has failed me, what i want to do seem very simple but i cant for the life of me work it out.
Please bare in mind that i am using Caliburn Micro for this application
I have a datagrid, which is bound to an ObservableCollection<Item> the items themselves handle changes using NotifyOfPropertyChange and a IsDirty flag, so editing these items is not an issue, however i cannot work out how to handle new items being added, we use the CanUserEditRows property of the datagrid to allow inline adding of new items.
However my problem comes when i try and detect a new item being added, in order to fire it off to my database services, it seems many people use the CollectionChanged event of the ObservableCollection in order to detect this, However this seem to fire the instant the user clicks on the {NewItemPlaceholder} part of the datagrid, before any data has been inserted.
private void ItemList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Item i in e.NewItems)
{
_itemManager.Insert(i);
}
}
}
This is the code i'm using, perhaps i've made a mistake, but i cant seem to work out how to get this to fire only AFTER the editing has finished, unfortunately google seems to be returning the same results no matter how i try and reword my question. Hopefully someone here can provide me with a relatively simple answer to this question.
If you need more code to show you how things work (such as the _itemManager) I can provide if needed.
It's very simple:
// instances of this type user should edit in data grid
public class Item : IEditableObject
{
// the item identifier
public int Id { get; set; }
// some data-bound properties
#region IEditableObject Members
public void BeginEdit()
{
}
public void CancelEdit()
{
}
public void EndEdit()
{
// new items has identifier, set to 0
if (Id == 0)
{
// post changes here
}
}
#endregion
}
DataGrid knows about IEditableObject, and if the bound data item implements this interface, grid calls corresponding methods during the editing.
I need some help here. Here is my situation:
I have a binding list which contains another binding list which I use as data source. below is an example:
Objects:
public class test
{
public string name { get; set; }
public BindingList<childs> childlist { get; set; }
}
public class childs
{
public string childname { get; set; }
}
I populate my radgrid by code. below is a preview:
private void form_Load(object sender, EventArgs e)
{
BindingList<test> testlist = new BindingList<test>();
/** I populate my list with data. I wont show this here. After the list is populated: **//
this.raggrid.MasterTemplate.Columns.Clear();
this.raggrid.MasterTemplate.AutoGenerateColumns = true;
this.raggrid.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
this.raggrid.MasterTemplate.Columns.Add(new GridViewTextBoxColumn("name", "name"));
GridViewTemplate template = new GridViewTemplate();
this.raggrid.Templates.Add(template);
template.Columns.Add(new GridViewTextBoxColumn("name", "childname"));
template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewRelation relation = new GridViewRelation(this.raggrid.MasterTemplate, template);
relation.ChildColumnNames.Add("childlist");
this.raggrid.Relations.Add(relation);
this.raggrid.DataSource = testlist;
}
The populating step works fine. But now, when the user edits the detail grid(named template from the code), I must update the binding list accordingly (named testlist from the code). I cannot seem to trigger an event when I edit the child grid. How do I achieve this?
Note: This is a winform application
PS: When I update the master template the binding list gets updated automatically as expected, but when I update the template I use as detail, it does not update the biding list.
Thanks,
Yash
For anyone having a similar problem, here is the solution:
Solution
Only thing is that I used CellValueChanged event instead of RowsChanged.