在Gridlight 3中使用Grid作为ItemsControl的ItemsPanel

skb*_*skb 11 silverlight grid silverlight-3.0

有可能做这样的事情:

    <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>
Run Code Online (Sandbox Code Playgroud)

项源类似于具有Text,Column和Row属性的对象List.

这可能吗?我真的希望我的数据网格是数据绑定的.

ito*_*son 3

您所做的将不起作用,因为 Silverlight 将每个项目(DataTemplate 的每个实例)包装在 ListBoxItem 中,并且 Grid.Column 和 Grid.Row 附加属性需要应用于该 ListBoxItem,而不是应用于成为的 TextBox该 ListBoxItem 的内容。

好消息是您可以使用 ListBox.ItemContainerStyle 在隐式 ListBoxItem 上设置属性。

坏消息是 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") });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

<local:GriderrificBox>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBox Text="{Binding Text}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <Grid />
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
</local:GriderrificBox>
Run Code Online (Sandbox Code Playgroud)

此代码(至少)有两个主要的缺陷:首先,您仍然需要在 XAML 中显式指定 ItemsPanel,即使该控件仅适用于 Grid 面板;其次,绑定路径被硬连线到代码中。第一个可以通过使用普通控件默认样式机制来解决,第二个可以通过定义诸如 RowBindingPath 和 ColumnBindingPath 之类的属性来解决,PrepareItemForContainerOverride 可以参考这些属性,而不是使用硬连线路径。无论如何,希望足以让你继续前进!