Bind to a particular row and column of a dynamic grid?

(Originally posted in the ...developer.winfx.avalon newsgroup, but this forum seems a little more lively.)
I'm new to WPF, so perhaps I'm going about this the wrong way. I'm
trying to create a grid that contains a collection of objects. The
number of rows and columns of this grid is dynamic; ideally those
properties would be bound to a couple of properties of a custom object.
The position of the objects within the grid would ideally be bound to
properties of those objects themselves.

A Grid allows items to be bound to particular rows/columns, but the
total number of rows/columns must be static (at least, from a pure XAML
perspective). The UniversalGrid allows binding to the total number of
rows/columns, but items cannot be bound to particular rows/columns (they
simply flow horizontally, wrapping with the number of columns).

Below is the closest I can get to what I want. Am I on the right track
Can anyone point me in a new direction I'm beginning to suspect it
may require some codebehind.

Thanks in advance,

-Phil

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

<Page.Resources>

<XmlDataProvider x:Key="InventoryData" XPath="Inventory">

<x:XData>

<Inventory xmlns="">

<Wafer rows="3" columns="3">

<Die row="0" column="0" value="One"/>

<Die row="1" column="1" value="Two"/>

<Die row="2" column="2" value="Three"/>

</Wafer>

</Inventory>

</x:XData>

</XmlDataProvider>

</Page.Resources>

<ItemsControl>

<ItemsControl.ItemsSource>

<Binding Source="{StaticResource InventoryData}"
XPath="Wafer/Die"/>

</ItemsControl.ItemsSource>

<ItemsControl.ItemsPanel>

<ItemsPanelTemplate>

<UniformGrid IsItemsHost="True">

<UniformGrid.Rows>

<Binding Source="{StaticResource InventoryData}" XPath="Wafer/@rows"/>

</UniformGrid.Rows>

<UniformGrid.Columns>

<Binding Source="{StaticResource InventoryData}"
XPath="Wafer/@columns"/>

</UniformGrid.Columns>

</UniformGrid>

</ItemsPanelTemplate>

</ItemsControl.ItemsPanel>

<ItemsControl.ItemTemplate>

<DataTemplate>

<Button Grid.Row="{Binding XPath=@row}" Grid.Column="{Binding
XPath=@column}" Content="{Binding XPath=@value}"/>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ItemsControl>

</Page>



Answer this question

Bind to a particular row and column of a dynamic grid?

  • Stephen Archer

    Hi Phil,

    Yes, I think you will have to populate the rows and columns for your "dynamic" grid in code - and yes, you are doing the right thing about binding to the attached properties from your model to position the elements in the various rows and columns.

    Thanks,
    -Unni



  • punamdahiya

    Hi Unni,

    Thanks for the suggestion. What I ended up doing, actually, is creating my own custom panel, DynamicGrid, that combines the abilities of the Grid (row/column binding) and UniformGrid (rows/columns binding). One interesting learning for me was that the ItemsContainer wraps each item within a ContentPresenter before placing it into the container. This means that any attached properties associated with each item (e.g. row and column) must be attached to the item's outer ContentPresenter rather than the item itself. This can be done by setting the ItemStyle property of the ItemsContainer to a style that applies only to type ContentPresenter and that sets the desired attached properties. This is not very elegant, but it works.

    Thanks,

    -Phil


  • Bind to a particular row and column of a dynamic grid?