I have a View that contains a Listbox. I'll call it CityListingPage.xaml. This list page has a CityListingViewModel, that is binded with the View like somewhat like this:
DataContext="{Binding CityListing, Source={StaticResource Locator}}"
This works nicely. Now I what to change my page to a Pivot Control, where the Pivot Items, would be instances of CityListingViewModel, but obviously with different constructor data (ie. Country)
I extracted the ListBox into a UserControl. Now I'm struggling how to make this work so that for each list I get a new instance of the CityListingViewModel.
I tried creating in the ViewModelLocator a collection of CityListingViewModels but how do I pass the a CityListingViewModel instance to the UserControls DataContext?
Perhaps there is a different, better way of doing this?
Without seeing your code, I'm going to do a little guessing, but I think you can do it directly via data binding. Since each pivot item is getting an instance of CityListingViewModel, you can just pass that binding along to the UserControl:
If you post a little more code showing what you're trying to do, we might be able to be of more help.
The following are two answers for using a collection to create panorama pages. But I am quite sure that the approach can be adapted to pivot pages:
Dynamically add eventtocommand actions to a listbox
Static and dynamic panorama items in a panorama wp7 mvvm
The second post should be more relevant.
If you are thinking of partitioning the same data over multiple views on a pivot page then I would suggest NOT using several view models, especially if it is the same datasource you are using for all the data.
Simply have a parameter which each view would bind to and use Linq to control what data is visible to that parameter.
So you will have the variable which will contain all the data to be displayed and one parameter per view querying that data.
Related
(I'm using Prism Dryloc) My application consists of two views. The first contains a single list view displaying strings and the second - an entry and a button.
The listview is bound to an observable collection in the first page's View Model. How can I add to the observable collection from a different view?
Great question! You're essentially trying to pass data between views, and there's several ways of passing data between Views in Xamarin.Forms.
The two ways that seem relevant for your case:
Either making the ObservableCollection a public static object (so there's only one global instance of it). Not recommended.
The better way is to use the messaging center so that the second page publishes an event when the button is pressed, that the first page is subscribed to. And it passes that information that gets added to the list.
If these don't work, elaborate your use case and I'll suggest some more
In cases where new items need to be added to a list via ajax, what is the biggest benefit of using something like Knockout.
So far what I have been doing is, on my view, use an editortemplate (with asscociated viewmodels) to render a list of items. Then to add a new item, I make a request to an action that loads a server-side viewmodel, and returns an EditorTemplte object which just gets appended to the list. Like this:
return Json(new { this.RenderPartialViewToString("MyEditorTemplate", model) });
The knockout way of doing things requires the implementation of another view model to display items, and then another template to display it. But doing it this way requires duplication of code since the view model has to be represented in 2 places: in the cserver side code and then the view for the knockout viewmodel. Isn't that bad practice?
Am I missing something, or understanding the purpose of knockout and MVVM?
The biggest benefit that you will see from Knockout is that you will not need to hit the server in order to add a new item to your list - everything happens client side. This has multiple benefits including:
You reduce load on your server.
You improve the end-user's experience.
You can keep multiple elements on the page up-to-date with your model without any server interactions.
Two great examples of this can be found at these Knockout tutorials:
Working with Lists and Collections
Loading and Saving Data
As far as duplicating code, if you take a look at those two tutorials, you'll notice that you don't need to duplicate code. For example:
Create a view to display your entire list.
To add a new item to the list, create a partial view that you load when you add a new item to the page - that partial view is bound to Knockout
When you submit the entire form, everything in that list will be submitted - including those items you added via Knockout.
Your ViewModel will be specific to your list item (you don't need to create an entire ViewModel for everything, necessarily). And your view is specific to a single list item.
Hope that's clear. Knockout is pretty straightforward and they have some great documentation and tutorials to help you move forward.
IMHO, the following is cleanest option for the architecture of knockout and asp mvc mixed together.
Have your ASP.net acting as a webservice and have knockout control all your view templating and logic.
Otherwise, yes there will be potential replication of viewmodels and having to refactor both front and backend code when you need to change your model.
I have a Model object with a List collection of sub objects. I need to load the form fields for the sub object to the page, and provide a link to dynamically add form fields for a second object. So in other words, multiple sub objects can be created via one form and one post back.
My first thought was just to put the form fields in a partial view and load the view via Ajax.ActionLink. This worked but the problem comes in when trying to uniquely identify each object in the collection and bind the collection of objects on postback. For this it seems the correct usage would be to use an #Html.EditorFor() helper, but I don't know how to call that via Ajax to dynamically add the object's editor template to the page when the link is clicked.
It sounds like you were on the right track with regards to a partial view, you'll just need to sort out the name property of your inputs so you can correctly bind to a collection of objects.
Have a look at this article by Phil Haack explaining how binding to lists works, or google for something more up to date with razor syntax.
I'd like to know how to set a single ViewModel throughout a single UserControl. I'm using an Items container inside a user control (bound to ItemsSource) and it doesn't seem to update with the code-behind replacement of a DataContext (to a code-behind instantiated ViewModel)
What i'm trying to do is change the DataBound foreground color of every text Item in the userControl, and the items inside an Itemscontrol dont seem to change. forcing a datacontext change removed the collection items from display.
I think I'm conceptually Misunderstood here. could anyone help?
I could fix the problem by using Storyboards to change color but the problem was still the same. The eventual solution was to access the resources inside the templates, which is possible by browsing the Visual Tree as shown in this tutorial
http://windowsphonegeek.com/tips/how-to-access-a-control-placed-inside-listbox-itemtemplate-in-wp7
The peculiar thing though, was that I needed to look for my object inside the initial object returned, as it seems to return the System generated one, which you don't see yourself. Looking for the answer inside this one helped. Also, pushing them into a list of items for easy access later could be a general idea, but MS needs to fix the way of doing this pronto.
I would recommend binding the ItemsSource to a property in your ViewModel.
There are two ways. May be both are stupid...
I have to display some collections of items.
First one.
I use DataTemplate for ListBoxItem.
Just set itemSource = myCollection;
That's all. Simple scheme.
Second one.
Each item in my collection has property view. It's a UserControl. That define how item renders.
Create DataTemplate with ContentPresenter only.
Binding Content property to a view.
Just set itemSource = myCollection;
That's all. More complex. But works too.
Has second one right to live? My doubt is that I have to create instance of UserControl for every item in my collection?
Is not it too expensive for collection with over than 500 items?
Thanks.
I don't believe there is much difference, with the DataTemplate approach the framework will create an instance of the DataTemplate for each item in the collection. In the second approach an instance of the user control will be created for each item, there may be a few more controls but only a few per item.
One reason the second approach could be preferable is that you can have logic around which content is bound. This could mean different user controls for each item in the list. Caliburn Micro lets you use this approach very naturally.