在Silverlight中使用UIElements作为ListBox的ItemsSource [英] Use UIElements as ItemsSource of ListBox in Silverlight
问题描述
我注意到,如果您有从 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
/ pre>
text2
text3
但是在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 $填充项目的逻辑c $ c>不被调用。
如果要获取行为,则需要将
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 aListBox
in Silverlight it renders the object as is and isn't paying any attention to settings ofDisplayMemberPath
and/orListBox.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
UIElement
s asItemsSource
in Silverlight the same way as any other objects? Or am I missing something?解决方案It looks like the issue is in the
PrepareContainerForItemOverride
method inItemsControlBase
class. If you look at that method in reflector you will see that if the item is aUIElement
then the logic to populate the items using theDisplayMemberPath
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 theListBoxItems
.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. TheDisplayMemberPath
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屋!