Until recently we have been using a highly customised version of the RadGridView to achieve a tile view approach in particular scenarios. Although this has worked well, every new release from Telerik seemed to result in ‘breaks’ in our custom code, and time spent correcting.
Given that we now have access to RadTileView in the Telerik WPF library, we were keen to replace our customisations with this Telerik supported control. However, as with most controls and libraries, things never quite work as you need them too so some ‘glue’ was needed to get a nicely functioning interface.
Integrating the RadTileView and RadFluidContentControl
As it currently stands, there is no in-built integration of the RadTileView and RadFluidContentControl. Someone has raised a Feature Request on the Telerik Public Issue Tracking System (ID 3461), but for the moment developers are pointed to the following documentation to achieve this goal:
The problem I have with the currently documented approach is that it’s unnecessarily complicated:-
1. You are expected to create (or modify) a business object to contain a ContentState property, and then bind the RadFluidContentControl State property to the aforementioned property on the business object, and create/use a converter

2. You also need to setup a two-way binding to that same ContentState property on each RadTileViewItem

Now I really do not want to be modifying/creating business objects to create the ContentState; it’s extra work, and is something that is providing a visual state tie between the two controls…nothing to do with my actual data…
Secondly, we end up having to setup two bindings to ensure both controls are properly synchronised via the same property.
A far easier/shorter approach is this:

This approach simply finds the RadTileViewItem, and binds the TileState of that item to the State of the RadFluidContentControl…that’s it aside from the state converter:
TileViewToFluidStateConverter
[ValueConversion(typeof(TileViewItemState), typeof(FluidContentControlState))]
public sealed class TileViewToFluidStateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
var contentState = (TileViewItemState)value;
switch (contentState)
{
case TileViewItemState.Minimized:
return FluidContentControlState.Small;
case TileViewItemState.Restored:
return FluidContentControlState.Normal;
case TileViewItemState.Maximized:
return FluidContentControlState.Large;
default:
return FluidContentControlState.Normal;
}
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
var fluidState = (FluidContentControlState)value;
switch (fluidState)
{
case FluidContentControlState.Small:
return TileViewItemState.Minimized;
case FluidContentControlState.Normal:
return TileViewItemState.Restored;
case FluidContentControlState.Large:
return TileViewItemState.Maximized;
default:
return TileViewItemState.Restored;
}
}
}
RadTileView Selection
Currently RadTileView does not have a SelectedItem property, but it does have a MaximizedItem property. So as long as you are using a suitable MaximizeMode, you can execute commands on the currently maximized item:

Binding Command
EditCommandParameter="{Binding ElementName=SupervisorTileView, Path=MaximizedItem}"
So although I’ve scrunched up the screen, I think it’s fairly obvious that the maximized item on the left is the one used with the toolbar.
However, this does mean if we change the MaximizeMode to either force or allow zero, you have states where there is no maximized item, e.g.

So the user has to maximize one for us to know which item the commands should execute against.
Integrating the RadContextMenu and RadTileView
We can expand on the aforementioned selection and execution of commands by integrating a RadContextMenu with the RadTileView.
In a previous post called WPF RadGridView and RadContextMenu: Simplifying Interaction in XAML, we looked at an easily repeatable approach to integrating these two controls.
We can apply much the same approach to the RadTileView:-
1. Define a new event name
XAML
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu>
<helper:AttachedCommand.CommandHelper>
<helper:CommandHelper EventName="RadTileView.RadContextMenu.Opened" />
</helper:AttachedCommand.CommandHelper>
2. Insert extra case in the CommandHelperChanged method in the AttachedCommand class
CommandHelperChanged
case "RadTileView.RadContextMenu.Opened":
RadContextMenuOpenedEventManager.RemoveListener(fe, commandHelper);
RadContextMenuOpenedEventManager.AddListener(fe, commandHelper);
break;
3. Modify the CommandHelper ReceiveWeakEvent method
ReceiveWeakEvent
if (managerType == typeof(RadContextMenuOpenedEventManager))
{
RadContextMenu menu = (RadContextMenu)sender;
if (menu.PlacementTarget is RadGridView)
{
GridViewRow row = menu.GetClickedElement<GridViewRow>();
if (row != null)
{
row.IsSelected = row.IsCurrent = true;
GridViewCell cell = menu.GetClickedElement<GridViewCell>();
if (cell != null)
{
cell.IsCurrent = true;
}
}
}
else if (menu.PlacementTarget is RadTileView)
{
RadTileViewItem item = menu.GetClickedElement<RadTileViewItem>();
RadTileView tileView = menu.PlacementTarget as RadTileView;
tileView.Tag = item != null ? item.Content : null;
}
}
This third step shows a workaround (read minor hack!) to the lack of a SelectedItem property/concept: it determines the RadTileViewItem the RadContextMenu is on, and sets the business object (item.Content) on the RadTileView Tag property.
Doing this, then allows us to Bind our command property in the XAML as follows:
XAML
<telerik:RadMenuItem Header="Edit" Command="{Binding EditCommand}"
CommandParameter="{Binding PlacementTarget.Tag,
RelativeSource={RelativeSource AncestorType={x:Type telerik:RadContextMenu}}}" />
Using the MaximizedItem property here would just confuse the user unless you limit the display of the context menu to only appear for the maximized item, as regardless of the item you are over you would always end up performing the action on the maximized item business object. By using Tag, we are able to allow the context menu actions to apply to the item they are over regardless of their state. So now the user has an alternate approach to executing commands that does not require an item to be maximized:

Print | posted on Thursday, 14 October 2010 11:04 AM