关于Silverlight:数据绑定时获取列表框的ItemContainer

关于Silverlight:数据绑定时获取列表框的ItemContainer

Getting at the Listbox's ItemContainer when data binding

有没有一种方法可以获取列表框中所选项目的ItemContaner? 我可以在Silverlight 2.0 Beta 1中使用,但是该容器在Silverlight 2.0的Beta 2中隐藏了。

当试图取消选择列表框项目的大小至特定大小以及将其选择为可变大小时,我正在尝试调整列表框项目的大小。 我还想获取动画所选项目的相对位置。 成长为可变大小并获得相对位置是为什么我需要进入列表框项的原因。

我应该澄清一下,我没有明确将项目添加到列表框中。 我在xaml和DataTemplates中使用数据绑定。 我遇到的麻烦是所选项目的DataTemplate的ItemContainer。


有一种方法可以获取包含项的UIElement以及项到UIElement的映射的Panel。您必须从ListBox继承(这实际上适用于任何ItemsControl),并重写PrepareContainerForItemOverride:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        var el = element as FrameworkElement;
        if (el != null)
        {
            // here is the elements's panel:
            _itemsHost = el.Parent as Panel;

            // item is original item inserted in Items or ItemsSource
            // we can save the mapping between items and FrameworElements:
            _elementMapping[item] = el;
        }
    }

这有点骇人听闻,但效果很好。


Silverlight 5更新。

1
2
3
4
5
6
              <ListBox ItemsSource="{Binding Properties}">
                 <ListBox.ItemTemplate>
                    <DataTemplate>
                       <TextBlock Text="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" />
                    </DataTemplate>
                 </ListBox.ItemTemplate>

现在支持RelativeSource AncestorType,使此操作更加容易。


看来您可以使用相对绑定从ItemTemplate获得Item Container。

1
<TextBlock YourTargetProperty="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBoxItem}}, Mode=OneWay, Path=YourSourceProperty}" />

我在这里找到了这个解决方案。


如果要将非UI元素(例如字符串或非UI数据对象)添加到列表框中,则可能很困难。但是,如果在将项目添加到列表框之前将它们包装在某些FrameworkElement派生的对象中,则可以使用TransformToVisual获取相对大小,并使用Height和Width设置项目的大小。

通常,您可以将对象包装在ContentControl中,如下所示。代替:

1
2
_ListBox.Items.Add(obj0);
_ListBox.Items.Add(obj1);

做这个:

1
2
_ListBox.Items.Add(new ContentControl { Content = obj0 });
_ListBox.Items.Add(new ContentControl { Content = obj1 });

现在,当您获得_ListBox.SelectedItem时,可以将其转换为ContentControl并设置大小并获取相对位置。如果需要原始对象,只需获取项目的Content属性的值。


推荐阅读