我想知道是否有办法在Xamarin.Forms的ListView中获取对DataTemplate内部视图的引用。 假设我有这个xaml:
<ListView x:Name="ProductList" ItemsSource="{Binding Products}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee" x:Name="ProductStackLayout"
Orientation="Vertical" Padding="5" Tapped="ListItemTapped">
<Label Text="{Binding Name}"
Style="{DynamicResource ProductPropertiesStyle}"/>
<Label Text="{Binding Notes}" IsVisible="{Binding HasNotes}"
Style="{DynamicResource NotesStyle}"
/>
<Label Text="{Binding Date}"
Style="{DynamicResource DateStyle}"
/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我希望能够获取名为&#34; ProductStackLayout&#34;的StackLayout的引用。在ListView的每一行。我需要在页面出现时执行此操作,以动态操作它的内容(对于通过数据绑定无法实现的内容),因此我无法利用传入的视图引用事件处理程序源自DataTemplate本身的元素,如ItemTapped或类似的东西。
据我所知,在WPF或UWP中,可以在VisualTreeHelper类的帮助下实现类似的功能,但我不相信Xamarin.Forms中有相同的类。
答案 0 :(得分:2)
是的,可以访问在运行时使用DataTemplate
创建的视图。来自XAML的BindingContextChanged
内的视图的隐藏DataTemplate
事件。在回调事件中,可以使用sender参数访问从DataTemplate
创建的视图。您需要输入发送者来访问视图,因为发件人被装箱为对象类型。
否则,您可以使用DataTemplate选择器根据您的对象创建视图。
答案 1 :(得分:1)
您还可以这样投射:
ITemplatedItemsView<Cell> templatedItemsView = listView as ITemplatedItemsView<Cell>;
ViewCell firstCell = templatedItemsView.TemplatedItems[0] as ViewCell;
StackLayout stackLayout = firstCell.View as StackLayout;
哪个会给您参考这些观点
但是您可能希望基于绑定上下文的更改做出反应,因为否则您将不得不手动更改视图的内容。
我怀疑使用BindingContextChanged
会使您渲染两次内容-首先,更改会导致渲染正常,然后再次渲染。因此,例如,如果发生字符串更改-标签将重新呈现-之后,您将在BindingContextChanged中获取值并执行您实际想要的呈现。
您可以继承ListView的子类,我认为这可以阻止它:
public class CustomListView : ListView
{
protected override void SetupContent(Cell content, int index)
{
// render differently depending on content.BindingContext
base.SetupContent(content, index);
}
}