I'm building a WPF order manager app and i've run into a situation i'm not sure how to deal with.
I want to re-bind the list of purchase orders requests for each order but i only want to do it if the the purchase order requests panel is visible in the app (they double click the order to show the list of purchase order requests). The problem i have is that the purchase order requests are a listbox inside each list item of the Order listbox and i can't find a way to traverse the controls in the list items (I can only iterate over the actual objects e.g. OrderInfo).
What i would like to do is
OrderListBox.FindName("PurchaseOrderListBox")
An example of the crm with 2 orders showing purchase order requests and 1 order not showing any
alt text http://www.readyflowers.co.uk/images/crm-datatemplate.png
The result i want to achieve
alt text http://www.readyflowers.co.uk/images/crm-datatemplate-saved.png
I'm not sure I understand your problem....
But it feels like you're trying to hack through the UI hierarchy to find something (ala WinForms) - this is like swimming against the tide in WPF. It'll make you tired real fast..
Look around for articles on the ViewModel pattern. One of them that I read is one by Dan Crevier. The basic idea is to have a Model object for the UI - the UI (data)binds to properties exposed by the ViewModel. Now all your UI related logic could go into the ViewModel, which is notified via propertyChanged notifications of any change in session state. So if a field changes, the ViewModel gets notified. The ViewModel updates relevant properties and the UI refreshes accordingly.
In this case ViewModel.OrderInfo.Find_PO_with_X(searchCriteria) will help you get to the right object. If found, you say ViewModel.ShowGreenLight = true and the UI control bound to this property will turn green.
HTH
Related
I've got the following problem: in our teams software you can navigate to a site (journal) which loads a individual history (journal entries). The history entries are currently shown in a grid. If you change the SelectedItem, additional data (details of the journal entry) is shown below the grid.
Now my team finds this Silverlight Timeline Control (Silverlight Documentation) pretty good for displaying historical data. I think this either.
My problem is that the only way to put data onto this timeline control is via XML files. That's not a viable solution for our project. Do you see a way to "bind" this to something like ItemsSource? The reason for this is that we have lots of "journals". And every journal you open shows a different history of journal entries. You also can add/edit/delete entries.
You can do this through ResetEvents method. Timeline control calculates event positions, so it needs all events to calculate position of any. It loads them quickly, though, so 10k of events should not be a problem. Please use timeline forum http://timeline.codeplex.com/discussions for more help.
Yes, add propery which calls reset events. This could be observable collection, subscribe to events of this collection and call reset events from there also. Makes sense?
I'm not really sure how to do this in the best MVVM way...
Basically, my main app opens up a search window that shows all records in a TabPanel. Then if a record is double clicked a new tab is opened with that record. Now, I'm trying to keep things MVVM, but I can't for the life of me figure out how to close the gui tabitem when a person deletes the record (why keep it open if the record is gone).
The only way I can figure out how to do it now is to pass the instance of the TabItem as a parameter of the DeleteCommand, which to me seems like a big no-no, but I can't for the life of me figure out how to accomplish this.
If you were going to do this in the true MVVM sense, then double-clicking a record would, behind the scenes, add a record to a collection of records. That record collection is the datasource for the tabs in your control. Simply removing that item from the list (usually an ObservableCollection<T>) would result in the UI updating and the tab being removed.
Which approach are you currently using to show the tab?
Edit (in response to comment):
That is not "true" MVVM. It doesn't matter if the tabs can be more than just records. You should create View Models which abstract those details, then just put your view model instances (RecordViewModel, ReportViewModel, etc) in an observable collection and bind to that. Use datatemplates to render the correct views for each tab's content based on the type of view model the current tab is being bound to.
Josh Smith wrote an amazing article describing how MVVM works. The sample application does something very similar to what you want to do.
The application displays a TabControl which displays 1 or more workspaces. The workspace area displays two different kinds of items. The tab items are closable. Take a look, I'm sure this will solve your problem.
WPF Apps With The Model-View-ViewModel Design Pattern
I'm working on a line-of-business silverlight application and I need a piece of advice concerning managing RIA services context lifetime.
Application - afer a few simplifications - is build of one big tab control. At the beginning there are 2 tabs: customer list and invoice list. These are plain datagrids with filtering/sorting and that sort of stuff.
User can add/edit customer or invoice selecting a row and double-clicking. Then the new tab is created with details of customer or invoice. User can open many tabs with different customers/invoices. After editing, user can save and close tab or just abandon edit and close.
The question is how to deal with data contexts.
Should I create one for customerlist and one for invoicelist and when user opens a new tab, I simply bind customer/invoive dataobject to control? This has an advantage that I dont need to refresh grids after saving changes. EDIT: This has some drawbacks. User can refresh grid - and what will happen to open detail tabs? User can also filter grid so some records being edited can be removed from datactx?
The other way is to create datacontext per tabitem. This is more safe but I need to handle refreshing grid(s).
I have no idea which method is better or maybe there is another alternative?
Use one ObservableCollection list in each case and it will automatically update the datagrids when items are changed.
I'm building a simple financial record-keeping application. The main window view model holds a list of Accounts. The view shows this list (in a ListView) along with a panel showing details about the currently selected Account.
At first, I bound the details panel and ListView's SelectedItem to the same property (of type Account) on the view model. However, I quickly realized that the details panel needed to be bound to an AccountViewModel, not directly to an instance of Account.
There are several ways to providing this AccountViewModel:
Bind the details panel to a separate property on the view model. When ListView's SelectedItem changes, the view model should create and set this new property to an instance of AccountViewModel that is associated with the selected Account.
Give the main view model a list of AccountViewModels instead of an Accounts list. Both the ListView listing all accounts and the details panel could then be bound to the same property on the main view model.
Have one AccountViewModel, changing the Account it references with each change to ListView's SelectedItem property.
Are there other options? Which choice do you recommend?
Thank you,
Ben
This is what I do:
Give the main view model a list of
AccountViewModels instead of an
Accounts list.
This will serve you well in many ways. I always find that eventually, for one reason or another, I need to augment my Models in some way to support a View, so these days I just start out by creating ViewModels.
The way you can tell that this is going to be a better option is that it involves less code. Less code always equals less bugs, in my opinion.
i like this option
Bind the details panel to a separate
property on the view model. When
ListView's SelectedItem changes, the
view model should create and set this
new property to an instance of
AccountViewModel that is associated
with the selected Account.
then you can bind the selected item to the view model and the details pane as well. this can be tested independently of the view. when you create your list of accounts you can also create a list of account view models, so when you change selection you are not having to create anything its all sitting there. this way your viewmodel is comprehensive, representing the whole screen not just floating bits of viewModel.
So far, the idea I like best is #3 from the original post for two reaons:
It has a 1 view to 1 view model correspondence, which I think best fits the M-V-VM pattern.
Since the account view model is told when to change to display details of a different account, it can ask the user if he wants unsaved edits to be saved before changing to display the new account (etc.).
I am developing a wpf desktop app with strict MVVM pattern.
Current my app is doing following things:
Showing a Treeview with HierarchicalDataTemplate.
User can expand or collapse Nodes.
User can add add new Nodes(Drag n Drop + double click).
Everytime a new Node is added Model is updated and Treeview is recreated based on Model.
Because Treeview is recreated, all nodes are shown as expanded after adding nodes.
I want to show nodes with their previous expanded condition. Is there any way to do this using MVVM ? What I have thought so far is
Model should not contain any data related to how to draw UI ??
VM should just get data from Model and put it in UI(and pass date from UI to Model) ??
Thanks for your thoughts. I may be way far out form rail. But just want to have some wisdom from you guys.
Thanks
PAIJA
If you haven't already, read this great article by Josh Smith: Simplifying the WPF TreeView by Using the ViewModel Pattern
Basically what he suggests there is to include a property called IsExpanded in your VM and bind the TreeView to it correctly so that the expanded/collapsed status is entirely controlled by the programmer.
One solution what I think could be is to stop the recreation of the tree, just update the model and only add nodeitems to the current node where you are dropping them. Just refresh the collections in model and dont refresh the tree. Let us know if this does't suits your architect.
Thanks,
Jagdev Josan
The view model can contain view related information, that is what it is for. It is a bridge between pure business and pure view. My view models usually expose a few business properties of an object and add a few related view properties. If all you need is business properties, then bind straight to the business layer. Its only when you need to do something like your situation here that you need a view model.
If you want to completely recreate the tree (which sounds crazy) you can store the expanded state of the nodes in your view model and bind them to the tree view items using an ItemsContainerStyle. that way when you recreate your tree view your previously expanded nodes will still be expanded.
So your wrapped business objects will contain an extra property IsExpanded that you can use to restore your tree view state.
P.s. did i mention its a bit over the top to recreate the tree view?