Это возможный сделать что-то вроде этого:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Text}" Grid.Column="{Binding Column}" Grid.Row="{Binding Row}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Источник объектов был бы чем-то как Список объектов, которые имели текст, свойства Column и Row.
Действительно ли это возможно? Я действительно хочу иметь свою сетку данных быть связанными данными.
То, что у вас есть, не будет работать, потому что Silverlight оборачивает каждый элемент - каждый экземпляр DataTemplate - в ListBoxItem, и присоединенные свойства Grid.Column и Grid.Row необходимо применять к этому ListBoxItem, а не к TextBox, который становится содержимым этого ListBoxItem.
Хорошей новостью является то, что вы можете устанавливать атрибуты для неявного ListBoxItem с помощью ListBox.ItemContainerStyle.
Плохая новость в том, что ItemContainerStyle не поддерживает привязку. Таким образом, вы не можете использовать его для установки присоединенных свойств Grid.Column и Grid.Row к атрибутам текущего элемента данных.
Одно из решений, которое я использовал, - создать подкласс ListBox и настроить привязку в PrepareContainerForItemOverride. Вот очень грубый, зашитый пример:
public class GriderrificBox : ListBox
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
FrameworkElement fe = element as FrameworkElement;
if (fe != null)
{
BindingOperations.SetBinding(fe, Grid.RowProperty,
new Binding { Source = item, Path = new PropertyPath("Row") });
BindingOperations.SetBinding(fe, Grid.ColumnProperty,
new Binding { Source = item, Path = new PropertyPath("Column") });
}
}
}
Использование:
<local:GriderrificBox>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Text}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</local:GriderrificBox>
В этом коде есть (по крайней мере) два основных недостатка: во-первых, вам все равно нужно явно указать ItemsPanel в XAML, хотя элемент управления работает только с панелями Grid. ; и, во-вторых, пути привязки жестко встроены в код. К первому можно обратиться, используя стандартный механизм стиля управления по умолчанию, а ко второму - путем определения таких свойств, как RowBindingPath и ColumnBindingPath, с которыми PrepareItemForContainerOverride может обращаться вместо использования жестких путей. Надеюсь, хватит, чтобы вы все равно начали!
Сетка
просто не подходит для использования, которое вы пытаетесь здесь разместить. Ожидается, что набор доступных строк и столбцов будет определен заранее, прежде чем вы начнете назначать элементы ячейкам.
Если вы пытаетесь создать список, который использует как горизонтальное, так и вертикальное пространство, возможно, лучше всего подойдет WrapPanel
из Silverlight Toolkit.
С другой стороны, если вы пытаетесь создать «сетку данных», рассмотрите возможность транспонирования или группировки столбцов в каждой строке модели, тогда вы можете использовать DataGrid
вместо ListBox
Если вы заинтересованы в поддержке такого сценария в будущей версии Silverlight, пожалуйста, проголосуйте за перенос макета Adobe Flex Grid , который будет отлично работают в таком сценарии