We have a list of items in a TreeView where users can select the item they want. Every item can be associated with another item. I have a button on my ItemEditor view that opens a new window with the associated item in read-only mode. The read-only copy of the item has no save functionality nor does it give any of the edits made by previous users. It does however share 90% of the fields, out of ~50.
Do I take the hit in almost duplicating the entire view and create a pure ReadOnlyItemViewModel? Or is it typically more acceptable to set flags in my view model to display which editable items are hidden?
You can map multiple views onto the same View Model. It's actually encouraged. You don't have to make a ReadOnlyItemViewModel...just make a View on top of the ItemViewModel. If you are trying to auto-generate the view, make whether it generates read-only or fully editable view a strategy of the generator. If you need more fine grain control consider adding attributes that express how a field should be displayed in Read-Only vs. Editable mode. Only after you've explored all those avenues should you consider splitting the VM into two.
Related
I have been tasked with creating a like for like user interface for a product replacement.
One of the components of the old system was a container that displayed properties in a hierarchy (think treeview like) where each property had a label and value (value could be a textbox, drop down, checkbox, file browse etc)
This is the component that I need to replace and one of the conditions being imposed on me is to front load it with about 5000 items, some of which will be made visible depending on usage context.
My first attempt has been to use a FlowLayoutPanel as the main container populated by TableLayoutPanels indented on left margin that each hold label and edit control.
I hit the problem of the 10,000 control handles limit.
Any suggestions on an alterantive approach to get round this limitation that will allow for the front loading of the 5000 items?
Thanks in advance.
Consider the following guidelines:
1. Do not load all the records at once. Load the data page by page as per request, and render each page of data.
2. Do not show all the records at once. You have a limited window size, even if you load all the data, just show the part that should be visible in the view port. Show the rest of the data when the user scrolls. This way you can dispose the previous elements.
3. Do not use a lot of handles. You can use a control which uses just 1 control handle, like a TreeView or DataGridView or even a custom control for yourself. The key is keeping data in view mode and just show the edit controls when the user focus on a specific item to edit.
Example: DataGridView and ListView controls support virtual mode for loading data. You can also simulate nested data by padding the first cell/item. Also the Treeview control supports events like BeforeExpand which allows you to load child data when the user requests.
For all above examples you can just show the edit controls when the user wants to edit the cell.
Is it possible in ExtJS to display different records from a store in different grids? I have a Store containing contact information (name, department, phone number) used to populate the contacts tab of my application. My goal is to be able to add grids elsewhere in the application that display contacts from specific departments (eg a grid for everyone in the tech department, another for everyone in the sales department). However, when I attach a filter, the filter seems to apply to the store itself, changing the display of all of the grids to the last version I try to load.
Do I need to create child grids and sync them to make this work?
No, it is not possible. The store gets filtered, not the grid itself. You do have to create multiple stores and assign a different one to every grid.
Another way to say it is that store (when used with a grid) is a ViewModel, that is, a model that is kept in sync with the view. Therefore, the same store can't be used for multiple views as you would expect.
No, but if you need a work-around, use same store for all the grids and filter store on grid's aftererender listener. But if you use these grids on tab then you need to do it on viewready event. Anyway, using same store for multiple grids will not be a good idea. Think twice before use.
I'd like to bind selected elements from a Grid to text boxes on a different page.
Can this be done?
If you mean completely separate pages, those screens only exist separately. When your "text box page" appears the previous "grid page" no longer exists. If it could be done my answer would be "Don't do it" as you would wind up with separate pages tightly bound to each other. That is considered a bad practice.
The latest Silverlight practices say that data should be shared via Models and View Models that live longer than the screens (lookup Silverlight MVVM patterns on Google). View Models are basically a place to move your code-behind to. The aim is to leave your XAML pages virtually code free.
Basically you want your screens to share common data. In this case that would include your current selection in a list of data items (you don't actually care if it was a grid that did the actual choosing).
The "grid screen" is bound to the data model to get its data source for the grid and also has its current selected item bound to an item in the data model. The same Model (or View Model) is bound to your "text box page" when it is created. The text boxes on that page are bound to the results previously stored in the data model.
One downside is that all bindable properties in data model/view Models have to be Dependancy Properties. If you do not make them bindable you get no error, just no data.
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.
Background
WinForms application using NHibernate. Application is in MDI style and each MDI child form opens a new NHibernate session at Load which remains open for the life of the form.
Question
My application is basically an "order management" or "purchasing" system. One particular form uses a lot of "lookup" lists. Like a list of products, a list of vendors, a list of locations, a list of UnitsOfMeasurement, a list of PriceQuotes, etc.
Lots of lists, that all get loaded when the form is constructed.
Problem: I need the lookup lists, but I need the form to be a bit faster to load. The form is taking too long to perform all the lookups. How can I get better performance and keep my lookup lists?
My Thoughts
Can I load the lookup lists once and hold on to them for the life of the application, and periodically check to see if the lists are stale?
Can I load just the text description for the lists, and instead of holding a bunch of IList, IList, etc, I could hold a bunch of IList, and then when I save, perform the Gets against NHibernate to get the real object.
Is there some other approach that I just haven't thought of?
You should definitely cache slowly changing data to improve performance. How often you need to check for stale data depends on the type of data and your business, e.g. units of measure probably doesn't change as frequently as a list of products. You should also provide a method for manually refreshing lists so that the user can refresh them if something appears to be missing.
If you need the business objects in the list in order to perform a database operation, you can call ISession.Lock(obj) to lock the object into the current ISession. One thing to be aware of is that the lock doesn't automatically cascade to child objects: I think there's a mapping setting to do that or you can do it manually.
Are you sending lists of full objects to your UI? I recently worked on an app using DTO's between the data layer and the UI so I'm not sending the full object, just a description and an identifier. That could help you trim out some unneeded data. So basically when the screen loads a service call is made, nhibernate gets all of the objects I want for my list box, then the UI binds to the list. I bound my listbox display member to the description and the value member to the identifier.