在Silverlight中使用UIElements作为ListBox的ItemsSource [英] Use UIElements as ItemsSource of ListBox in Silverlight

查看:170
本文介绍了在Silverlight中使用UIElements作为ListBox的ItemsSource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,如果您有从 UIElement 导出的任何东西作为Silverlight中的 ListBox 中的项目,它将呈现该对象原样,并没有注意 DisplayMemberPath 和/或 ListBox.ItemTemplate 的设置。



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

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

在Siverlight中,这会产生一个 ListBox 像这样:

  text1 
text2
text3
/ pre>

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

  tag1 
tag2
tag3

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

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

产生:

 code> a 
f

有没有办法使用 Silverlight中的UIElement 作为 ItemsSource 与任何其他对象相同的方式?或者我缺少某些东西?

解决方案

看起来像 PrepareContainerForItemOverride c> c> cControlBase 中的$ c>方法。如果您在反射器中看到该方法,您将看到如果该项目是 UIElement ,则使用 DisplayMemberPath 不被调用。



如果要获取行为,则需要将 ListBox 控件子类化并覆盖此方法并设置您想在 ListBoxItems 上设置的值。



这是一个例子:

  public class MyListBox:ListBox 
{
protected override void PrepareContainerForItemOverride(DependencyObject element,object item)
{
if(!object.ReferenceEquals(element,item))
{
ContentControl control = element作为ContentControl;

if(control == null || this.ItemTemplate == null)
{
return;
}

control.Content = item;
control.ContentTemplate = this.ItemTemplate;
}

}
}

而你需要有一个 ItemTemplate 才能使其工作。 DisplayMemberPath 属性实现起来稍微复杂一点。

 < local:MyListBox Width =200Height =300DisplayMemberPath =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,并将其设置为实现控件的程序集。



祝你好运!


I've noticed that if you have anything deriving from UIElement as items in a ListBox in Silverlight it renders the object as is and isn't paying any attention to settings of DisplayMemberPath and/or ListBox.ItemTemplate.

For example if you have XAML like this:

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

In Siverlight this produces a ListBox with items like this:

text1
text2
text3

However in WPF (and I think this is correct behavior) it lists tags as expected:

tag1
tag2
tag3

If I use objects that aren't inherited from UIElement everything works as expected:

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

Produces:

a
f

Is there any way to use UIElements as ItemsSource in Silverlight the same way as any other objects? Or am I missing something?

解决方案

It looks like the issue is in the PrepareContainerForItemOverride method in ItemsControlBase class. If you look at that method in reflector you will see that if the item is a UIElement then the logic to populate the items using the DisplayMemberPath doesn't get called.

If you want to get the behavior you are after you would need to subclass the ListBox control and override this method and set the values you want set on the ListBoxItems.

Here is an example:

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;
        }

    }
}

And you need to have an ItemTemplate for this to work. The DisplayMemberPath property is a little more complicated to implement.

<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>

Don't forget to add the xmlns for the local and set it to your assembly that implements the control.

Good luck!

这篇关于在Silverlight中使用UIElements作为ListBox的ItemsSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆