代码之家  ›  专栏  ›  技术社区  ›  Alan Mendelevich

使用uielements作为Silverlight中ListBox的项源

  •  0
  • Alan Mendelevich  · 技术社区  · 15 年前

    我注意到如果你有什么 UIElement 作为一个项目 ListBox 在Silverlight中,它将对象呈现为原样,而不关注 DisplayMemberPath 和/或 ListBox.ItemTemplate .

    例如,如果您有这样的XAML:

    <ListBox Width="200" Height="300" DisplayMemberPath="Tag">
        <TextBlock Tag="tag1">text1</TextBlock>
        <TextBlock Tag="tag2">text2</TextBlock>
        <TextBlock Tag="tag3">text3</TextBlock>
    </ListBox>
    

    总之,这会产生一个 列表框 有这样的项目:

    text1
    text2
    text3
    

    然而,在WPF中(我认为这是正确的行为),它按预期列出了标签:

    tag1
    tag2
    tag3
    

    如果我使用的对象不是从uielement继承的,则一切工作正常:

    <ListBox Width="200" Height="300" DisplayMemberPath="[0]">
        <sys:String>abcde</sys:String>
        <sys:String>fgh</sys:String>
    </ListBox>
    

    生产:

    a
    f
    

    有什么方法可以用吗 铀元素 S AS ItemsSource 在Silverlight中,与任何其他对象的方式相同?还是我错过了什么?

    2 回复  |  直到 11 年前
        1
  •  1
  •   Dave Clemmer manu    11 年前

    看起来问题出在 PrepareContainerForItemOverride 方法在 ItemsControlBase 类。如果你在Reflector中看到这个方法,你会发现如果项目是 UIElement 然后使用 DisplayMemberPath 不会接到电话。

    如果你想得到你所追求的行为,你需要将 ListBox 控制并重写此方法,并设置要在其上设置的值 ListBoxItems .

    下面是一个例子:

    public class MyListBox : ListBox
    {
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            if (!object.ReferenceEquals(element, item))
            {
                ContentControl control = element as ContentControl;
    
                if (control == null || this.ItemTemplate == null)
                {
                    return;
                }
    
                control.Content = item;
                control.ContentTemplate = this.ItemTemplate;
            }
    
        }
    }
    

    你需要一个 ItemTemplate 为了这个工作。这个 显示成员路径 属性的实现有点复杂。

    <local:MyListBox Width="200" Height="300" DisplayMemberPath="Tag">
        <local:MyListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Tag}" />
            </DataTemplate>
        </local:MyListBox.ItemTemplate>
        <TextBlock Tag="tag1">text1</TextBlock>
        <TextBlock Tag="tag2">text2</TextBlock>
        <TextBlock Tag="tag3">text3</TextBlock>
    </local:MyListBox>
    

    不要忘记为本地添加xmlns,并将其设置为实现该控件的程序集。

    祝你好运!

        2
  •  0
  •   Dave Clemmer manu    11 年前

    例如,微软对Silverlight和WPF都进行了不同的编码,但Silverlight 3.0中仍然缺少许多依赖属性功能。

    现在看看你的代码,就意味着 DisplayMemberPath 在Silverlight中,依赖对象无法正常工作,但目前仅对纯CLR对象有效。但是,如果您在Microsoft Connect网站上发布bug,他们可能会想出一个更新。

    sl 3.0中的依赖属性仍然是新的,因此我们希望在sl 4.0中看到一些改进。如果您使用Reflector,您将看到StackPanel和所有基本控件在这两个地方的实现上都有很大的不同。