Hello i am trying to create a grid in xmal that is populated via a ViewModel.
The grid is a 5x5 grid, and my ViewModel contains a list of "MyObject". This object contains 2 int variables Row and Column witch indicates where in the grid the Object should be.
MyObject is also a view models, and the grid space should be filled with Data Template names MyTemplate with the MyObject as the DataContext.
Now I pretty new to xaml and view models, but how would the best way of doing the be?
Let's see...
Put an ObservableCollection into the VM, then...
Option 1:
...a simple Grid into V. Subscribe to it's CollectionChanged event from xaml.cs, add ContentControls for each Added object to grid, bind the ContentControl's Grid.Row and Grid.Column property to each object's properties, and set the DataContext to the object itself and ContentTemplate to Resources["MyTemplate"]. (Also, for any removed objects find the corresponding ContentControl and remove it.)
Pro: easy
Con: .cs, no designer support
Option 2:
...an ItemsControl into V. Set its ItemPanelTemplate to a Grid, and bind your ObservableCollection to its ItemsSource. Then set your Itemtemplate to MyTemplate. Now, the trick is to make the items put in the correct cell, based on your values. For that, use the ItemsControl's ItemContainerStyle property, and bind the container's Grid.Row and Column to those properties.
Pro: nice xaml and easily extended
Con: ItemContainerStyle is tricky in WPF and missing in Silverlight, so in case of the latter, you can forget it
Option 3:
...a custom panel which you write. Inherit it from Grid perhaps. Than if an element is put into it, check if it's DataContext implements an interface which contains your properties. Then use this as an ItemsPanel in Option 2...
Pro: it should work perfectly
Con: You have to write a new Panel for this...
Hopefully one of these 3 will be ok for you.
Related
How do I bind all corresponding elements of several arrays?
Wendt's book Cocoa shows an example binding a property, a slider, and a textfield in IB. Change any one and the other two track its value. It's very simple. Wendt strongly makes the point that controllers are not necessary in simple cases.
I would like to extend this to binding an array of properties, an array of sliders, and an array of textfields. Change the 3rd slider, for example, and the 3rd property and 3rd textfield should change accordingly.
But would an NSArrayController be of any benefit in this case? I plead ignorance because all the examples I've found show NSArrayController used only with NSTable.
I have an inspector pane in my app that contains a bunch of controls. These controls are bound to my model objects through an NSArrayController. Depending on what type of object is selected I am displaying a different set of inspectors (just like how IB works). The inspector controller observes the array controller's selection, so that it can load the required set of inspectors when the selection changes.
The problem is that the old set of inspectors isn't removed apparently. Even through the inspector controller doesn't hold a strong reference to them and they are removed from their superview, they still stick around and log binding errors to the console:
[<Circle 0x102107df0> valueForUndefinedKey:]: this class is not key value
coding-compliant for the key width.
My guess is that the NSArrayController holds a strong reference to the controls because of the bindings. Is this possible? Do I manually have to remove a binding before removing a control from the superview? How do I properly implement an inspector pane like this?
EDIT: The documentation says
Neither the receiver, nor anObserver, are retained.
so I guess bindings should be removed automatically when removing the control, shouldn't it?
The problem is that there isn't a defined order between the inspector controller's response to the selection changing and the various inspector views updating themselves in response to the same thing. So, the "wrong" inspectors for the new array controller selection are still there for a brief time, at least, and trying to access non-existent properties of the element objects.
One fix would be to not rely on key-value observing the array controller selection to switch the set of inspectors in and out. Rather, have a coordinating controller – whichever is controlling the "selected object" based on the user action – clear the set of inspectors before changing the selection and not switching in the new set of inspectors until after it has been changed.
I want to Bind UserControl in the ItemTemplate section of the GridView.
UserControl contains nothing but with decorated text..
I had been using Collection which consisted of and was binding Content directly within ItemTemplate within the main xaml page, which was easy.
But now my collection is changed to .. How do I bind now?
Don't put UserControls in the model (i.e. your collection). They belong in the view (i.e. your XAML page).
I'm guessing you replaced the String you used originally with a UserControl because you want to use a different UserControl for different items. Take a look at ItemTemplateSelector. You can bind it to a DataTemplateSelector inside which you can decide which template to use based on the individual item. You can now have a custom class for the Content and a property inside it to select the UserControl based on it.
I am trying to get my head around MVVM and the Navigation-based project template in SL4. At the moment I am trying to move the ContentFrame_Navigated event handler into the ViewModel. Basically this event handler checks each hyperlink button in the menu bar against the current page and adjusts the style accordingly. To do this it seems I need to pass the EventArgs as well as another object. I see MVVM Light has the PassEventArgsToCommand bit, but what about passing another object/control? In this case it's the StackPanel hosting the list of menu item hyperlinks. I'm just getting my head around the MVVM concept, what's the best practice in this case?
Cheers,
Dany.
With MVVM you have to think more abstract. You are not daling with a list of HyperLink elements, but with a list of Navigation Targets. I.e. you should separate the presentation (HyperLink elemen) from the data (the URL, the Title, whether the item is selected or not, etc.). You now hold the data in a list on your ViewModel (normally you would see this data as the ViewModel of your Hyperlinks, and name it accordingly). The items are held in a ObservableCollection so that you can track changes if a item is added etc.
To display this list you can use a class inheriting from ItemsPresnter (e.g. a ListBox) and use binding to set the properties. Now you navigate to a page you can set the IsSelected property of the relevant item in the list, resetting all other IsSelected properties.
As the navigation targets can be seen as a global collection, you can also hold it in a property on the ViewLocator, so that all Views and ViewModel can access this list, and setting the IsSelectedProperty is applicable to all Views. This global collection represent you navigation state.
And, BTW, the EventToCommand, the RelayCommand, and the Command attribute ony support one parameter. Furthermore, from experience I can advise you that it is not good practice (although you obviously can do it) to mix View objects, such as EventArgs, or elements and your ViewModel.
one solution is to put the menu items the ViewModel, and the View can bind this list.
then the View wouldn't need to send the menu items to the ViewModel
So I have a task of reading from an xml file which contains a description of what form fields and comboboxes should exist in a dialog. I started by using NSForm and addentry to add the form fields, but then found out NSMatrix may be required to add combobox cells dynamically.
So my questions are:
1) Since NSForm inherits from NSMatrix can I add combobox cells to NSForm after I add the text fields.
2) If I have to use NSMatrix, does anyone have any good sample code they can point me to or write which adds a text field, and combobox to it at runtime and then resizes the NSMatrix to fit its contents. A lot of books just describe what NSMatrix is, and show how to populare it using interface builder.
NSForm does not allow custom cell types (text field only) and NSMatrix takes only one cell type (you cannot have an NSMatrix that has a mix of NSTextFieldCell and NSComboBoxCell).
If you really need to create a variable number of rows of field + combo box, you're going to have to manage the creation, layout, and destruction of these manually.
Alternatively, you might consider using collection views.
Update - If you're targeting 10.7 and up and need better control than collection views offer, consider using view-based table views.