How can I update my ribbon with context items based on the selected view and view model? - prism

In my Prism application, I have a ribbon which I want to be able to update with context commands based on the currently active view and view model. I have my ribbon updating with context commands when a view is opened initially (in OnNavigatedTo), but I can't figure out how to update my ribbon as the user clicks between items in my tab control.
I'm planning on using Prism's IEventAggregator to send an "active view changed" event when the user clicks on a new tab, and then have each view model subscribe to that event and have the view model update the ribbon if the active tab item is that view model's tab. The problem is that I need my event data to include some parameters that specify what the active tab contains, but I don't know how to determine which view model is linked the active tab control item.
How do I know what view model corresponds to a tab control item, or is there another way of solving this problem?

You can just let the view model of the selected tab do the work, no need to over-complicate things:
xaml:
<TabControl SelectionChanged="OnSelectionChanged"/>
code-behind:
private void OnSelectionChanged( object sender, SelectionChangedEventArgs e ) => (((sender as TabControl)?.SelectedContent as FrameworkElement)?.DataContext as IRibbonAwareViewModel)?.OnSelected();
interface implemented by the tab's view model:
internal interface IRibbonAwareViewModel
{
void OnSelected(); // <-- here the view model updates the ribbon
}

Related

Xamarin Forms - Slide out menu to select items

I have a xamarin forms application search screen that allows a user to select an item from a list. Currently I am using a picklist and the user has to scroll and select and click done. This is using the native controls. Howerver I have noticed in iOS in settings menu etc where the have designed it so that when a user want to select from a list a arrow is shown on the right hand side which takes them to another page to select an item (s) from a list. To me this seems like a better UX. Here is an ex:
My question is there something built into this withing xamarin forms? I guess I could create a listview and then on click pass to another page. Any examples are appreciated.
There is no built-in for that, but it's not too hard to achieve this.
To set the disclosure indicator (the arrow), implement a custom renderer derived from ImageCellRenderer and override GetCell
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var viewCell = base.GetCell(item, reusableCell, tv);
viewCell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
return viewCell;
}
When the user taps that cell you should navigate modally to the view showing the list of languages.
Adding that Cancel-Button is not really hard either, but needs another step. You'll need to wrap the new language selection page in a NavigationPage and push that NavigationPage modally. Furthermore you'll have to add a toolbar item to the wrapped page (see here).
Within the page there is a SearchBar view and a ListView below it. To add the checkmarks, you'll have to implement a custom cell with a custom renderer (derived from ImageCellRenderer like the one shown above), setting the UITableViewCell.Accessory to Checkmark if the custom cell is selected
if(item is SelectableCell selectableCell)
{
var selected = selectableCell.IsSelected;
viewCell.Accessory = selected ? UITableViewCellAccessory.Checkmark : UITableViewCellAccessory.Checkmark;
}
Please note: Selectable cell is no Xamarin.Forms stock cell, but one that you have to implement by yourself, including the bindable property IsSelected.
This should be basically the steps you need to achieve what you want. I've assumed basic Xamarin.Forms knowledge that is needed to fill the gaps.

Change menubar items based on current NSViewController

I have NSViewControllers for things like Orders and Clients. These all live inside a tab view controller. When I'm on the Orders, tab, I want the File->New to say New Order, and likewise New Client on that controller.
If I implement validateMenuItem: and change the name it's not just for that controller. This means that every single view controller I create would have to reset the name back to just New.
How do I change titles of a menu item dynamically, based on the currently selected NSViewController?

How do I create a dynamic page based on a selection?

I am trying to dynamically fill a second panorama page based on what item was selected from the home application screen.
On the application's first start screen there is a listbox if items each with text. If a user taps on an item with text "foobar" a template page should load and the title of the template page should be set to "foobar" and this second panorama page should know that it's data should be related to "foobar".
Is there anyway to do this?
I currently have my MainPage navigate to a new page (DynamicPage.xaml). This navigation is triggered when a ListBox_SelectionChanged event occurs. I have the title text of the DynampicPage.xaml Binding to a TitleText variable that is located in MainPage.xaml.cs. However, when I do this the title of DynamicPage.xaml is ever only set to my initialization value for the titleText variable even though I am updating this variable right before I navigate to the page.
If anyone can provide some help I would be very grateful as I am just a beginner on the WP7 platform. Thanks!
The Binding you're using for the title is only going to update if the TitleText property is a dependency property or if your MainPage is implementing the INotifyPropertyChanged interface so your class can notify the UI when one of its properties changed.
http://windowsphonegeek.com/articles/All-about-Dependency-Properties-in-Silverlight-for-WP7
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.95).aspx
But I think this is not the best way for you to achieve this. For now a much better way is to store your data somewhere in a static class, in the main page's constructor load these data into the listbox, and when the user selected an item, navigate the user to the second page like this:
NavigationService.Navigate(new Uri("/DynamicPage.xaml?Item=" + selectedItem.Id, UriKind.Relative));
When you navigate like this a new instance of DynamicPage is created, and in the OnNavigatedTo method you can access the navigation parameters and populate your page with the selected data. For example:
<controls:Panorama x:Name="MyPanorama" Title="TitleHere">...</controls:Panorama>
Item selectedItem = StaticData.GetItem(NavigationContext.QueryString["Item"]);
MyPanorama.Title = selectedItem.Name.ToUpper();
Description.Text = selectedItem.Description;
This way you can use secondary tiles and toast notifications to directly point to a specific content in your application.
If you're getting to understand the navigation you should definitely use the pattern called Model-View-ViewModel which is about to solve these problems mostly with bindings, but trust me, probably this is the easier way for now.

Can a view controller own a sheet?

I want to call a sheet from within a view controller (user clicks on a button and the sheet will be displayed). Can the sheet have a separate window controller (with outlets and actions) or does the view controller from which the sheet is called operate as the sheet's controller?
I'm trying to determine how to display a sheet from a separate Interface Builder (.xib) file than my view controller. The sheet will have a list based on a popup menu item, so I would like to put that "logic" in a separate controller. I tried using a NSWindowController, but that didn't work.
A stock NSViewController controls a view; nothing more. You can make a custom subclass that owns the sheet, or you can make it own a window controller which owns the sheet. The choice is yours.
Tried using a NSWindowController, but that didn't work.
You should ask another question about that.

Sharing viewmodel to multiple views using Caliburn.Micro in WP7

I am currently working on a project which requires multiple views of the same viewmodel. Let me describe this way:
ViewModel: CustomerDetailsViewModel.cs (inherited from Screen class)
View: CustomerDetails.cs (this view has CustomerDetailsViewModel as datacontext and this set automatically by Caliburn.Micro)
View: CustomerInfo.cs (now this is the view where I want to share CustomerDetailsViewModel, which could have some data already modifed via CustomerDetails view)
I am currently using NavigationService to navigate to CustomerInfo view. Is there any way to pass the reference of current viewmodel to the view which user is navigating to in caliburn.micro?
Thanks in advance
idev
Use the attached property cal:Bind.Model="{Binding}" to bind the view to the view model.
See http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions "View First" section.
Alternatively you can also look into the cal:View.Context="MyContext" attached property as described here: http://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition "Multiple Views over the Same ViewModel" section.
Add a property or two to your App.xaml.cs. What ever you put in here will persist throughout the lifetime of the application (keep in mind that tombstoning will cause this property's value to be lost though). If you want to pass a ViewModel then setyour associated property in App.xaml.cs to the view model and then when the new page loads have it read from that same property.

Resources