This is a migrated thread and some comments may be shown as answers.

MVVM approach with region adapter and different views for different tile states

6 Answers 95 Views
TileView
This is a migrated thread and some comments may be shown as answers.
JC
Top achievements
Rank 1
JC asked on 06 Oct 2011, 06:23 PM
Hello, I want to use the RadTileView with prism regions and MEF.  I found the excellent sample provided by support illustrating a region adapter for MEF in prism doing just this and it works great.  (Last post in the thread here: http://www.telerik.com/community/forums/silverlight/tileview/binding-tileviewitem-header-to-viewmodel-in-prism.aspx)

My issue is that I want to determine the best MVVM way to offer two different views in the tile depending upon whether the tile is maximized or minimized.  When a tile is minimized I want to offer a useful view containing data that can be displayed in a minimized view and when the tile is maximized I want to provide an alternate working view.

This is similar to Windows 8 metro in that a minimized tile still can show updates and useful information then be maximized and offer a full ui.

I'm having trouble wrapping my head around how to do this in MVVM / Prism / MEF beyond the sample provided in the link above.

Is it two different views and the region name needs to be alternated depending on the tile state?  Or perhaps one view that can morph itself depending on the containing tile state? Or something better...?

Any assistance would be greatly appreciated.

6 Answers, 1 is accepted

Sort by
0
Accepted
Tina Stancheva
Telerik team
answered on 11 Oct 2011, 05:55 PM
Hello Jc,

There are a few approaches that you can use to implement such a scenario, but I believe that the best one is to wrap the views, you add to the RadTileView, in a RadFluidContentControl. Then you'll be able to take advantage of the built-in state-changing logic of the control. Basically this control exposes three different content properties - Content, SmallContent and LargeContent. Only one of these three properties is visible at any given time. Moreover, you can control the logic that defines which content to be visible.

This is why integrating the RadFluidContentControl with the RadTileView control in a PRISM scenario will allow you to inject one view of type RadFluidContentControl and then switch its content based on the RadTileViewItem.TileState. You can even create new regions in the RadFluidContentControl - make each content a region and then inject different views based on the type of content - Small, Large or normal.

I attached a sample project to get you started. Please have a look at it and let me know if it helps.

Regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
JC
Top achievements
Rank 1
answered on 11 Oct 2011, 10:28 PM
Ahhh...good idea, thanks Tina, you guys are the best, I'll have a look at the sample.

Cheers!
0
JC
Top achievements
Rank 1
answered on 12 Oct 2011, 02:28 AM
Hi Tina that is a great idea and works great in the sample unfortunately I'm a bit stuck trying to convert the Galasoft MVVM Light utility library you used to standard stock Prism for silverlight and commanding using DelegateCommand.

I have my command and the code declared in my shell view model as you did however I'm stumped on wiring up to the command.

This is a snippet from my viewmodel:
//declaration
public DelegateCommand<object> ChangeStateCommand { get; private set; }

//instantiation in constructor
 ChangeStateCommand = new Microsoft.Practices.Prism.Commands.DelegateCommand<object>(ChangeState, CanChangeState);
            
etc etc standard DelegateCommand stuff.

In my shell view is where I hit the wall, this:

 <telerik:RadTileView 
            prism:RegionManager.RegionName="MainTileRegion"
            TileStateChanged="{Binding ChangeStateCommand}" 

I get an XamlParseException, specifically: "Failed to assign to property 'Telerik.Windows.Controls.RadTileView.TileStateChanged'."

What should I be looking into to bind this properly?
0
Tina Stancheva
Telerik team
answered on 12 Oct 2011, 08:45 AM
Hi Jc,

At the moment the RadTileView control doesn't support your scenario since it doesn't have commands support. Basically RadTileView.TileStateChanged represents an event and it cannot be bound to a command property.

You'll need to use EventTriggers and EventToCommand behavior to attach a Command to the TileStateChanged event and MVVMLight also allows you to pass the event arguments to the command thus giving you access to the tile, which state is being changed. And this is why I used it in the sample application. However, I logged an item to implement commands support for the TileStateChanged event and you can vote for this feature here.

Also, there is another approach that you can use. Instead of controlling the TileStateChanged event logic from a command, you can bind the State property of the RadFluidContentControl and change it depending on the TileState property of the TileItems using a converter. Such an MVVM approach is described in this article. Give it a try and let me know if you need more info.

Kind regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
JC
Top achievements
Rank 1
answered on 12 Oct 2011, 05:16 PM
Thanks Tina, that is very helpful and I'm learning a lot from this.

Now that I know how the FluidContentControl works and for this particular scenario I just need the FluidContentControl to automatically change it's state based on the containing TileView's state (each view consumes the same data anyway so I don't need a completely different view model for each state).

Since this is not really something which drastically breaks MVVM and is in the shell only, I've added a handler for the TileStateChanged event in my shell view xaml and then in the code behind just added the following code which appears in the docs:

private void tiles_TileStateChanged(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            RadTileViewItem item = e.Source as RadTileViewItem;
            if (item != null)
            {
                RadFluidContentControl fluidControl = item.Content as RadFluidContentControl;
                if (fluidControl != null)
                {
                    switch (item.TileState)
                    {
                        case TileViewItemState.Maximized:
                            fluidControl.State = FluidContentControlState.Large;
                            break;
                        case TileViewItemState.Minimized:
                            fluidControl.State = FluidContentControlState.Small;
                            break;
                        case TileViewItemState.Restored:
                            fluidControl.State = FluidContentControlState.Normal;
                            break;
                    }
                }
            }
        }

This causes the content to display as I want it to.  Seems like there should be a more automatic way for this to happen though.
0
Tina Stancheva
Telerik team
answered on 14 Oct 2011, 11:32 AM
Hello Jc,

I see your point on the matter and we have a feature suggestion to integrate the RadTileView control with the RadFluidContentControl. You can vote for it from our PITS and if the item gathers enough popularity, we will definitely consider implementing it.

Thank you again for your feedback.

Kind regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
TileView
Asked by
JC
Top achievements
Rank 1
Answers by
Tina Stancheva
Telerik team
JC
Top achievements
Rank 1
Share this question
or