Question

I have a one column grid, with rows of varying heights in a WPF application. The items in the grid are dynamically generated, and will be added and removed at run-time.

For each row that is added, I would like a GridSplitter row to be inserted between each element.

I currently bind the model data via an ItemControl, and use AttachedProperties to obtain the element row count (obviously the eventual solution will have a higher number of rows to include the GridSplitters):

<ItemsControl ItemsSource="{Binding MyModel}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid local:GridHelpers.RowCount="{Binding MyModel.RowCount}" local:GridHelpers.ColumnCount="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

The MyModel variable is an ObservableCollection which contains ViewModel objects. The RowCount is a member variable which returns the number of elements in the collection.

How can I insert a GridSplitter between each of the rows?

I would like each element and GridSplitter to be generated from a template. However, if the GridSplitter is contained within a template, it doesn't work due to the presence of a ContentPresenter as its parent rather than a Grid. I'm running out of ideas, apart from creating my own UI element which has its own splitter component written from scratch. There must be an other way surely!

Many thanks for your help.

Was it helpful?

Solution 2

Well, after a considerable amount of reading, I think I have found the best solution, for those who may wish to do the same thing.

I implemented something similar to how the ColumnResizerAdorner works in the core WPF library. It may also be worth looking at the ResizingAdorner example in MSDN's WPF sample.

I have a class for the adorning, which adds a Thumb to a VisualCollection. A class for handling thumb dragging events. This class is aware of the Grid row definitions, and resizes them accordingly.

OTHER TIPS

I assume that your GridHelpers static class defining the RowCount property is responsible for dynamically generating new RowDefinition for each item in the ItemsSource.

For 2nd item and all subsequent ones, instead of adding a RowDefinition your code should add two row definitions - one for the item and one for the splitter. Then the code should also add a gridsplitter with Grid.Row value of the first of the two RowDefinitions you dynamically add. It would always be odd.

    var gs = new GridSplitter();
    gs.SetValue(Grid.RowProperty, x); //x = the RowDefinition you are generating
    gs.ResizeBehavior = GridResizeBehavior.PreviousAndNext;
    gs.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
    gs.VerticalAlignment = System.Windows.VerticalAlignment.Top;
    gs.Height = 3; //or whatever other height you desire.

Then add another RowDefinition for the item itself. Don't forget to set the Grid.Row property for the item to the even rowdefinition

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top