如何从ListView中的模板化数据中获取UIElement



好吧,我觉得这个问题有点愚蠢,但是,每当我"myListView.Add(new MyClass())"时,winrt平台都会在那里添加一个新的UIElement,并将适当的属性正确地绑定到它们适当的UIElement中,现在,我希望能够迭代这些逻辑项(myListView.items或myListView.SelectedItems),并获得它们对应的UIElement用于动画,这可能吗?

例如

class PhoneBookEntry {
    public String Name { get;set }
    public String Phone { get;set }
    public PhoneBookEntry(String name, String phone) {
        Name = name; Phone = phone;
    }
};
myListView.Add(new PhoneBookEntry("Schwarzeneger", "123412341234");
myListView.Add(new PhoneBookEntry("Stallone", "432143214321");
myListView.Add(new PhoneBookEntry("Statham", "567856785678");
myListView.Add(new PhoneBookEntry("Norris", "666666666666");

在XAML中(只是一个例子,我可以解释我的意思)

<ListView.ItemTemplate>
     <DataTemplate>
         <Grid>
              <TextBlock Text="{Binding Name}"/>
              <TextBlock Text="{Binding Phone}"/>
         </Grid>
     </DataTemplate>
</ListView.ItemTemplate>

所以,我的观点和目标是

foreach(PhoneBookEntry pbe in myListView.Items) // or SelectedItems 
{
    UIElement el; // How can I get the UIElement associated to this PhoneBookEntry pbe?
    if(el.Projection == null)
        el.Projection = new PlaneProjection;
    PlaneProjection pp = el.Projection as PlaneProjection;
    // Animation code goes here.
    if(myListView.SelectedItems.Contains(pbe)
        //something for selected
    else
        //something for not selected
}

我只需要一种方法来获得一个UIElement,它用于在模板化列表视图中表示这个逻辑数据类PhoneBookEntry。此外,这种必要性也带来了一个很大的问题,我在Windows Phone上选择的项目在视觉上没有差异——有什么想法吗?

您还可以使用ListView.ContainerFromItem或ListView.ContainerFromIndex方法,这些方法将返回列表视图中给定项目的容器UI元素(当然,仅当生成容器时)

好吧,我在回答自己的问题时可能看起来像个傻瓜,但我已经找到了解决办法。

首先:ListViews只为列表中的确定项(缓存的项和显示的项)创建UIElement。因此,如果您将2000个项目添加到myListView.items中,则表示这些项目的UIElements的有效弹药数将为56或接近数字。因为,ItemListView模拟UI元素,即使它们不在那里,只是为了给滚动条提供大小和位置(因此,为什么在非常大的列表上向下滚动会导致一些滞后,WinRT正在卸载UI元素并加载新的)

从中,我发现我可以简单地通过迭代当前加载的UIElement列表

// For each of the cached elements
foreach(LIstViewItem lvi in myListView.ItemsPanelRoot.Children) 
{
    // Inside here I can get the base object used to fill the data template using:
    PhoneBookEntry pbe = lvi.Content as PhoneBookEntry;
    if(pbe.Name == "Norris")
        BeAfraid();
    // Or check if this ListViewItem is or not selected:
    bool isLviSelected = lvi.IsSelected;
    // Or, like I wanted to, get an UIElement to animate projection
    UIElement el = lvi as UIElement;
    if(el.Projection == null)
        el.Projection = new PlaneProjection();
    PlaneProjection pp = el.Projection as PlaneProjection;
    // Now I can use pp to rotate, move and whatever with this UIElement.
}

就这样,就在我的眼皮底下。。。

最新更新