Question

TreeGridView Column Span?

Posted 2 months ago by Avatar Cory J. Geesaman

Is it possible to apply a column-span to a TreeGridView cell based on a property in the databinding (e.g. by type?)  I'm trying to add a special node type which spans all the columns as a grouping/separator element.


Comments (5)

Posted 2 months ago by Actipro Software Support - Cleveland, OH, USA

Hi Cory,

While you can't really do an arbitrary column span, in the PropertyGrid we change the "row" (PropertyGridItem) style using a custom style selector on the PropertyGrid.ItemContainerStyleSelector property that chooses between the normal PropertyGridItem style for properties and another for categories.  Since our style for category items doesn't include a TreeListViewItemRowPanel, the style's template content will span all the columns.  You could do something similar in TreeListView, as PropertyGrid inherits TreeListView.


Actipro Software Support
Posted 2 months ago by Cory J. Geesaman

Do you have an example of something like this I could look at?  I'm trying to use intellisense to find these via a style selector similar to the breadcrumb code sent over (assuming I can just add a binding to the type of item referenced once I get far enough with it to span columns) but am not able to find it.

Posted 2 months ago by Cory J. Geesaman

The primary hangup I'm running into is how to leave the normal ItemContainer intact and select only for the specific data context type - it seems the ItemTemplateSelector might be a better fit for this purpose, but leaving the default intact when not of the matched type is an issue.  What I have thus far will match the type I'm looking for, but breaks the normal items:

<grids:TreeListView.Resources>
<Style TargetType="grids:TreeListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="grids:TreeListViewItem">
<TextBlock>test</TextBlock>

<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="{x:Type common:TaskGroup}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</grids:TreeListView.Resources>
Posted 2 months ago by Actipro Software Support - Cleveland, OH, USA

This is effectively the source code for ours.  If you leave the default Style null (like our PropertyStyle) in this case, it should use the default Style.  Then you set an instance of this StyleSelector to your TreeListView.ItemContainerStyleSelector property and set its various Style properties like CategoryStyle to a Style with a new Template.  That template should fill the width.

public class PropertyGridItemStyleSelector : StyleSelector {
		
	public Style CategoryEditorStyle { get; set; }
	public Style CategoryStyle { get; set; }
	public Style PropertyStyle { get; set; }

	public override Style SelectStyle(object item, DependencyObject container) {
		var categoryModel = item as ICategoryModel;
		if (categoryModel != null)
			return this.CategoryStyle;
		else {
			var categoryEditorModel = item as ICategoryEditorModel;
			if (categoryEditorModel != null)
				return this.CategoryEditorStyle;
			else {
				var propertyModel = item as IPropertyModel;
				if (propertyModel != null)
					return this.PropertyStyle;
			}
		}

		return null;
	}

}

Actipro Software Support
Posted 2 months ago by Cory J. Geesaman

Thanks, this helped a lot, my two big sticking points with this were not knowing to return null and where to place the StyleSelector, my version ended up looking a bit different so I could get around some parts of the inheritence chain and give priority to styles which are a nearer match:

StyleSelector:

public class ProjectListTreeViewItemStyleSelector : StyleSelector
{
    public List<Type> NullTypes { get; set; } = new List<Type>();
    public Dictionary<Type, Style> Templates { get; set; } = new Dictionary<Type, Style>();

    public ProjectListTreeViewItemStyleSelector() : base()
    {
    }

    public override Style SelectStyle(object item, DependencyObject container)
    {
        var itemType = item.GetType();
        foreach (Type t in NullTypes)
        {
            if (itemType == t) { return (null); }
        }
        foreach (Type t in Templates.Keys)
        {
            if (itemType == t) { return (Templates[t]); }
        }
        foreach (Type t in Templates.Keys)
        {
            if (itemType.IsSubclassOf(t)) { return (Templates[t]); }
        }
        return (null);
    }
}

 XAML:

<grids:TreeListView.ItemContainerStyleSelector>
    <local:ProjectListTreeViewItemStyleSelector>
        <local:ProjectListTreeViewItemStyleSelector.NullTypes>
            <system:Type>common:TreeNodeModel</system:Type>
            <system:Type>common:RootTreeNodeModel</system:Type>
        </local:ProjectListTreeViewItemStyleSelector.NullTypes>
        <local:ProjectListTreeViewItemStyleSelector.Templates>
            <Style x:Key="{x:Type common:TaskGroup}" TargetType="grids:TreeListViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <TextBlock>test</TextBlock>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </local:ProjectListTreeViewItemStyleSelector.Templates>
    </local:ProjectListTreeViewItemStyleSelector>
</grids:TreeListView.ItemContainerStyleSelector>
Information The latest build of this product (2018.1 build 0673) was released 1 month ago, which was after the last post in this thread.

Add a Comment

Please log in to a validated account to post comments.