ContextualTabGroup.ItemsSource gives strange behavior

Ribbon for WPF Forum

Posted 7 years ago by Rory Plaire
Version: 12.1.0560
Platform: .NET 4.0
Environment: Windows 7 (64-bit)
Avatar

Background:

In WPF, we have ItemsControls which expose an ItemsSource dependency property. The behavioral contract which is established for the items control is that given a collection of objects and setting ItemsControl.ItemsSource to that collection, for each object derived from UIElement, the element will be rendered and for all other types, a TextBlock is generated and the Text property is set to the results of "ToString()" called on that instance, unless a DataTemplate is set and the template data type matches the instance type, in which case the template is applied to the instance and the resulting visual tree is used for the item display. This is important because ContextualTabGroup is an ItemsControl, but problems arise when attempting to use it like this.

Issue:

When a ContextualTabGroup is created, and the ItemsSource is bound to a collection of (view-model) objects, and an ItemTemplate is set, an error is generated by the OnValidateItems method in the ContextualTabGroup: System.ArgumentException - "Only Tab controls may be added as items of a ContextualTabGroup." This issue is observed in the following code:

public class MvvmTabGroup : ContextualTabGroup
{
	public MvvmTabGroup()
	{
		var labelBinding = new Binding { Path = new PropertyPath("Label") };
		SetBinding(LabelProperty, labelBinding);

		var factory = new FrameworkElementFactory(typeof(Tab));

		ItemTemplate = new DataTemplate(typeof(TabViewModel))
						   {
							   VisualTree = factory
						   };

		var itemsSourceBinding = new Binding
							   {
								   Path = new PropertyPath("Tabs")
							   };

		SetBinding(ItemsSourceProperty, itemsSourceBinding);
		IsActive = true;
	}
}

 Note that a DataTemplate is being specified which should translate the instance found in the collection to a visual tree the root of which is a Tab. If I override ContextualTabGroup.OnValidateItems and don't call the base class, later on, the ribbon expects the object to be a Tab without ever performing a template instantiation and application: "Unable to cast object of type 'TabViewModel' to type 'ActiproSoftware.Windows.Controls.Ribbon.Controls.Tab'." This occurs in ContextualTabGroup.OnItemsChanged.

Expected result:

I want to be able to bind the ItemsSource to an arbitrary collection of objects in order to support my MVVM architecture and use ItemTemplate to generate the visuals. This would follow the behavioral expectation set with all other WPF ItemsControl controls. Is there a workaround or some modification to a subclass of ContextualTabGroup I can implement in order to achive this end?

Comments (8)

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rory,

At the moment, the ContextualTabGroup isn't set up properly to allow MVVM bindings.  But we can try and enhance it to support this.  Would you mind preparing a new simple sample project that shows how you'd like to use this feature and email that over?  We'll use it to debug and make sure our code changes work.  Please rename the .zip file extension so it doesn't get spam blocked.


Actipro Software Support

Posted 7 years ago by Rory Plaire
Avatar

Hi again.

Here's a sample which shows how we usually work with WPF ItemsControls in terms of tabs and how we'd like to do it with the ribbon. An ItemsControl is really straightforward with MVVM - just provide the items, the binding and a template, and the ItemsControl creates a container for the template and instantiates it with the item as the DataContext. This is really all we're looking for.

 

EDIT: Apparently I can't figure out how to attach a file to the issue. Here's a link to the archive: http://sdrv.ms/OGXnKo

[Modified 7 years ago]

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rory,

Thanks for the sample.  We've looked into things further and unfortunately found it would take a larger redesign of internal code than initially suspected to support this the right way for MVVM.  I have marked down your request on the TODO list and will retain the sample.


Actipro Software Support

Posted 7 years ago by Rory Plaire
Avatar

Fair enough.

However, the thing that's really tripping me up is that the ContextualTabs ItemsControl only accepts Tab controls. This really breaks down the ItemsControl contract, which is that the items in the ItemsSource can be any object, and the ItemsControl will generate an ItemContainer element and instantiate a visual tree from a corresponding DataTemplate for it. That's really the core issue in this case, since we've worked around the lack of MVVM support other than that.

[Modified 7 years ago]

Posted 7 years ago by Rory Plaire
Avatar

Can I get any further feedback from Actipro on the specific issue of the ContextualTabs ItemsSource exception?

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

We have a typed collection of ContextualTabGroup objects in Ribbon.ContextualTabGroups.  Changing that to be more ItemsSource-like would cause breaking changes throughout our code, and there are other similar scenarios down the line.  Like Tabs to Groups, etc.  So unless we'd revise it all, I'm not sure making changes for the contextual tab groups would make sense.


Actipro Software Support

Posted 7 years ago by Rory Plaire
Avatar

But it shouldn't matter, since the control should be able to generate the containers (ContextualTabGroup objects, in this case) to place in ContextualTabGroups given a collection of items and a DataTemplate. This is how all other ItemsControl controls do it, why break the contract?

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Rory,

What happens now is that the Ribbon.ContextualTabGroups (which is a typed collection of ContextualTabGroup items) is being used as the ItemsSource for an ItemsControl in the Ribbon's control template.  Ideally the Ribbon.ContextualTabGroups would be an IEnumerable instead of a typed collection (and if we rewrote the control from scratch again, it would be), but at the moment a lot of internal code relies on the ContextTabGroup visuals being realized already directly via that collection.  And similar for other areas in Ribbon.


Actipro Software Support

The latest build of this product (v2019.1 build 0681) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.