I'm working on a Silverlight 4 WCF RIA Services app. I created a Presentation Model for my Stock entity, which is working fine. My trouble (well, one of my troubles) is when I try to databind a combobox to lookup a StockType.
I can set the combobox items source in xaml all OK (i.e. I can see the list of items in the dropdown), but the selected item is not bound to the CurrentStock.Type property. CurrentStock is a property on my viewmodel, and it's working fine for all the other fields, just not the comboboxes.
<Combobox
ItemsSource="{Binding Source={StaticResource StockTypeDataSource}, Mode=TwoWay}"
DisplayMemberPath="Type"
SelectedValue=="{Binding Path=CurrentStock.Type}"
SelectedValuePath="Type"/>
I believe this is because the combobox data source is in a different domain context to my StockPresentationModel entity, am I right? If so, can I work around that, or do I need to pull the Stock_Type entity into my Stock presentation model? Or can I somehow load my entities (Stock and Stock_Type) into my viewmodel and correctly set the combobox items source from there?
This is my first project using Silverlight and RIA, and I have hunted and searched and experimented for an embarrassing amount of time, so any help would be much appreciated.
Make sure that you have [Include] attribute in Type property in Metadata of entity class of RIA service.
Related
Core Data model
I have a many-to-many relationship between two of the principal entities; call them Item and Tag. There will be a large number of Documents. Each may have 0 to an arbitrary number of tags.
Each Item entity relevantly has an attribute called name, and a to-many relationship to Tag called tags. Each Tag entity relevantly has an attribute called name, and a to-many relationship to Item called items.
To display them, within the same window, I have: (i) an NSTableView (itemTableView), fed by an NSArrayController (itemArrayController), showing all Items; and (ii) an NSTableView (tagTableView), fed by a different NSArrayController (tagArrayController) showing all Lists.
tagTableView
In the tagTableView, the Table View is bound to tagArrayController, with controllerKey arrangedObjects.
There is only a single table column. The textfield in it is bound to Table Cell View, to model key path objectValue.name. That works so far; it displays all of the lists as expected, and sorts properly when I add a sort descriptor.
Everything has been set up using interface builder in Xcode.
The problem
I have added a checkbox into the tagTableView, in the same table column as the textfield. I am trying to implement two things:
The checkbox should be checked if the user has previously associated the Item with the relevant Tag. If not, the checkbox should be unchecked.
If the user checks an unchecked checkbox, I want to establish a relationship between the two; if the user unchecked a checked checkbox, I want to break that relationship.
The underlying behavior pattern is that the user will not necessarily have control over the tags and may not be able to create them. They are to choose from existing tags, and therefore should be able to see which ones exist, and be able to check/uncheck those that apply.
However, I can't see how to implement this.
Part solutions so far
I can see a possible way to do at least the first task programmatically, roughly along these lines:
Monitor tableViewSelectionDidChange for itemTableView
For a change, update the data source for tagTableView manually, and work out checkbox state by checking them for those Tags which relate to the Item entity that has just been selected, and otherwise unchecking them
However, this looks likely to add complexity, and ideally I would like to do this with bindings if possible.
I have reviewed the Apple Core Data and Bindings references, all the Cocoa books I have, stack overflow and I've also done extensive googling. I have found lots of similar questions (e.g. http://lists.apple.com/archives/cocoa-dev/2011/Mar/msg00164.html) but no answers.
I've also found a way that might work programmatically, but which seems to be like my idea above, at the expense of being able to use bindings (e.g. http://www.raywenderlich.com/14742/core-data-on-ios-5-tutorial-how-to-work-with-relations-and-predicates)
The only relevant question on this site -- Core-Data Check Box Cell with many-to-many data -- is not answered to a level that I can make use of.
It would seem to me that this should be a prime candidate for bindings. I should be able to ask the itemArrayController what Tags (if any) have a relation to its selected item, and then set the checkbox to ticked if it matches the relevant Tag, and unset it if it doesn't. I would expect I should be able to do this within the bindings for the checkbox itself, in interface builder. But I can't work out what model key path or binding to use, or what to set the cocoa bindings for the checkbox to. Am I missing something obvious? Thanks
I'm creating an app which shows the status of a number of servers. This information is retrieved from an API and stored in an observable collection (ObservableCollection) on my view model.
Each instance of the ServerDetails Object should have a PanoramaItem. I'm trying to do this through Binding in the xaml.
Any ideas if this is possible?
Yes it is.. here is a helpful blog, WP7 but will be relevant for WP8
http://devlicio.us/blogs/derik_whittaker/archive/2012/08/22/data-binding-to-the-panorama-control-in-wp7.aspx
basically, you need to set the ItemSource, and a DataTemplate / ItemTemplate for the panorama items. The method is the same with Pivot/Pivot Items there are also plenty of blogs for those.
I am developing a WinRT app which has many user roles. The View of many pages in my app change based on the Userrole
For eg. I have a Student role and a Professor role. When the Student logs in he will see personal-info, performance chart, todos and badges received and when a professor logs in she will see her personal-info, todos and feedback received
How do I only show the components which are necessary?
Is binding Grid.Visibility a good way of doing this or is there any better way?
Update:
By doing it the way suggested by #Ahmed(answers below) I will be loading all the controls in the design and only change the visibility of it. My page will still be heavy.
Is there anyway where I can load only the controls which I wish to see
There are certainly many ways to compose your UI.
You can use Visibility as suggested to show or hide various parts of your UI.
You can use VisualStateManager to show or hide various views or even change the templates.
You can use an ItemsControl with ItemTemplateSelector to display different items based on the input collection from the view model - e.g. for a student the ItemsSource of the ItemsControl would be bound to a collection of view models for personal-info, performance chart, todos and badges received and for a professor you would get view models for personal-info, todos and feedback received. The ItemTemplateSelector would provide a different view of these specific items.
You could also use an ItemsControl with ItemTemplateSelector to display different views of same view models depending on the user role that you would pass to the selector.
You could use a ContentControl with a custom ContentTemplateSelector that would provide a different view based on the user role information provided in the view model bound to the Content property.
You can write some code behind to show/hide/add/remove UI components based on the user role.
You can encapsulate various views (badges, personal info, feedback, etc.) in separate UserControls per view and use any of the above techniques to show/hide specific views.
You can design a different page for a different user role and depending on the role - navigate to a specific page.
Finally you can create separate apps for different user roles.
All of the above would strongly benefit from using the MVVM pattern. The choice of a technique or rather combination of techniques would depend on what information you want displayed, how it's supposed to be laid out, how maintainable you want it to be vs. how quick to initially develop, how secure you want it to be and finally how much you know, are willing to learn or have time to do so.
If there are not too many roles - I would personally probably create a separate app for each role and reuse as much of the code as possible, though that would also depend on some other requirements - like the ability for two people to access the system from the same device. I wouldn't use the show/hide techniques at all since that still requires the UI to be loaded, use up memory etc. Most apps have some sort of a central hub/dashboard implemented as a GridView or some other layout and display shortened previews of the data/links to go to detailed views or full lists. This is where I would provide different data in the view model for different roles. Detail pages would likely not need as much customization since the data would look mostly the same for each role or be inaccessible to some roles at all. Depending on permissions of course some people might be allowed to edit or see more/less of the data. For such smaller differences you could use template selectors, provide different data from the view models and control edit button visibility using command bindings.
The answer might be pretty broad and vague since a lot here depends on your specific design and requirements.
you can make your own converter something like this, that will change visibility based on roles
public class RoleToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var user= value as User;
if(user!= null) {
return user.IsInRole((string)parameter) ? Visibility.Visible : Visibility.Collapsed;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And in your XAML you can use your converter to set control's visibility like this
<Control Visibility={Binding Path=CurrentUser, Converter={StaticResource RoleToVisibilityConverter}, ConverterParameter=Student }/>
I have written a phone app using an MVVM framework. It came together okay - every page (view) on the phone has its own ViewModel and code within each ViewModel went away to the dataservice and retrieved appropriate data.
So I had a page showing an Agenda of upcoming items and its ViewModel retrieved a collection of events and within the XAML I bound a Listbox to this collection.
Similarly I had another page showing a OneOff Events and again, within its VM I called the data service to get a collection of data back and that was bound to a listbox within its view.
Not sure how good an implementation of MVVM this is, but, I ended up moving to a different database - and it was very easy to implement another dataservice without touching anything else and it all worked great.
Ok - so now I am looking to rework this app into a Windows Store app. I now have a main page that will show a combination of data that on the phone was shown on individual pages.
Hypothetically, assume that the Agenda items and One Off Events mentioned above are now appearing on the same main page (so much more room to show stuff)
Just struggling with what this means for ViewModel(s). If the MainPage can only work with one ViewModel, do I end up with one huge ViewModel that includes all the functionality that was in multiple VM's before.
Or should the Main ViewModel have within it collections of ViewModels. From looking around this seems to be the way it could be done, but, if so where are the ViewModels created?
It seems quite a fundamental shift from what I have done previously.
Yes, you can set different ViewModels as the binding context for different parts of your page. You can use the Locator pattern (one locator object with ViewModel properties) or Dependency Injection to keep the construction of things manageable.
Great sample code and slides by Gill Cleeren that discuss and show how the Contoso Cookbook sample application can be set up alternatively using MVVM and a ViewModelLocator class can be found here. The talk itself is on channel 9.
From these slides:
Data binding is the glue but...
A view needs to “find” its ViewModel
ViewModel is the DataContext
Can be static or dynamic
Static: View creates ViewModel and sets it as DataContext
Dynamic: at runtime, View selects its ViewModel or vice-versa
2 options:
View-First: ViewModel gets created because View is created
ViewModel-First: ViewModel is created and View gets selected
I have inherited some Silverlight\WCF code and now need to implement some new features. I fairly new to Silverlight\WCF so my question may be rather basic. So...
I have a listbox in Silverlight that binds to a resource that is a List<> returned from a WCF (rest) service (which is just reading values from a db table). I have implemented the ability to add new items to the db table through a WCF service and now want to make my listbox update once it has been added to the db.
It is possible that my initial code needs to change so I have listed the relevant lines below.
In xaml the resource is as such:
<CollectionViewSource x:Key="myWCFSvc">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription Direction="Ascending" PropertyName="ID" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
And the binding of the listbox is:
ItemsSource="{Binding Source={StaticResource myWCFSvc}}
And the .cs has in the callback
((CollectionViewSource)LayoutRoot.Resources["WCFSvc"]).Source = myList;
So now if a user adds a new entry through another Silverlight childwindow an new entry is created in the db and I want to update the listbox to include this entry. I'm unclear how to do this.
I know there are observablecollections and INotifyPropertyChanged but unsure if this is those are what I need, or how to use them in this context. I searched around a bit but the examples I found don't seem fit my scenario.
Your original thoughts are correct, the type you are looking for is the ObservableCollection<T>.
If you replace your existing List with this then as changes are made to its membership by other code it will notify other interested parties such as the CollectionViewSource, which in turn will notify anyting that is binding to it.