views:

325

answers:

2

I am currently trying to build a ControlTemplate for an ItemsControl that uses the Grid as its ItemsPanel where each item is stacked horizontally and delimited with a GridSplitter.

The basic goal is to have a dynamic bindable ItemsControl where all items stack up in a row and where each item can be resized with a splitter.

There are two things I can't wrap my head around: How is the GridSplitter supposed to end up automatically between each item? How do I set Grid.Column for each item.

If this can't be done with a simple control template what would be a common and good way to implement something like this? Do I need to write a new ItemsControl for this?

I need actual (Grid)Splitter controls so there can be custom ControlTemplates for them. Also I think it would come in quite handy to have the additional layout functionality for the cells (GridLengthUnitType, Stretch, Alignment).

So when rolling my own I guess I would need a custom ItemsControl (that generates the splitters for each item) and a custom panel (that behaves like a onerow/onecolumn grid - so no need for the attached Grid.Row, Grid.Column properties, .Orientation would suffice) that can take Splitter controls and knows how to deal with them in terms of layouting.

What do you think of this approach? Is the preferred or a good way?

A: 

You need to put the gridsplitter in its own column. Assuming the grid will only have one row, there is no need to set the Grid.Row for any item. If you want, though, you can set it to 0 (the first row).

This might be a good reason to write your own custom container, though. Maybe based on the stackpanel instead of the grid. I believe that the gridsplitter will effect the size of the items on either side of itself (I think what you want is for it to shift all except for te one it is resizing).

Gabriel McAdams
I think you mixed up rows and columns. As I said, in the above scenario I want the items to stack up in a row (so lots of columns here) and I need to add lots of gridsplitters between the columns of the items. Of course one could easily imagine that the same thing applies with vertical orientation.
bitbonk
Ok. Then switch rows and columns. I changed my answer accordingly.
Gabriel McAdams
I need actual (Grid)Splitter controls so there can be custom ControlTemplates for them. Also I think it would come in quite handy to have the additional layout functionality for the cells (GridLengthUnitType, Stretch, Alignment). So I guess I would need a custom ItemsControl (that generates the splitters for each item) and a custom panel (that behaves like a onerow/onecolumn grid - so no need for the attached Grid.Row, Grid.Column properties, .Orientation would suffice) that can take Splitter controls and knows how to deal with them in terms of layouting.
bitbonk
I understand what you are saying about having the ability to use a ControlTemplate for the GridSplitter. And I agree with you about the stretch and alignment properties. The only issue I see is (again) that the GridSplitter shrinks the cell on one side as it expands the one on the other side. It sounded like you wanted the GridSplitter to effect the size of only one item at a time (and shift the rest up or down).
Gabriel McAdams
+1  A: 

My understanding is that the ItemsControl is based on the idea that for each item it only creates and adds one control to the itemshost. Creating both a GridSplitter and the default itemcontainer per item goes against this principle.

Since you only have one column, and only want to resize vertically, i'd suggest writing your own panel, which behaves like a StackPanel but always leaves a gap of a few pixels between the child elements. If the mouse is over this gap, and the user begins to drag, the panel can resize the nearest child elements.

So the resize logic would have to be implemented on the custom panel., which is think the biggest drawback, but IMO well worth it because it is tucked away in one place only. You don't need to do anything special in your ItemsControl/ItemTemplate/ItemContainerStyle other than use this Panel as itemshost.

You could also use a standard StackPanel and add mouse handlers to it which implement the resize logic. But then you'd have to set a margin in your ItemContainerStyle to create the gaps.

Bubblewrap
There is just one problem. I need to be able to write a control template for the splitter part.
bitbonk
Ah, i see...i dont think using an ItemsControl is an option then...
Bubblewrap