我在列表视图中显示了一个自定义单元格。应该的
但我担心的是,它的工作,我不明白为什么。
我来给你安排一下,因为有点复杂。
我使用不同类型的自定义单元格来显示联系人列表的每一部分(有一个标题单元格、一个搜索单元格等等)。
在这里,
ContactsPage
包含listview和datatemplate的声明。
<ContentPage>
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="HeaderTemplate">
<ViewCell>
<StackLayout>
<local:HeaderView/>
</StackLayout>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="SearchTemplate">
<local:SearchCell/> //<=== Important
</DataTemplate>
<DataTemplate x:Key="CategoryTemplate">
<ViewCell
x:Name="CategoryCell">
<Label
Text="CategoryCell" ></Label>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="SelectionTemplate">
<ViewCell
x:Name="SelectionCell">
<Label
Text="Selection Cell" ></Label>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="ContactTemplate">
<ViewCell
x:Name="ContactCell">
<Label
Text="{Binding FirstName}" ></Label>
</ViewCell>
</DataTemplate>
<local:ContactDataTemplateSelector x:Key="TemplateSelector"
HeaderTemplate="{StaticResource HeaderTemplate}"
SearchTemplate="{StaticResource SearchTemplate}"
CategoryTemplate="{StaticResource CategoryTemplate}"
SelectionTemplate="{StaticResource SelectionTemplate}"
ContactTemplate="{StaticResource ContactTemplate}"/>
</ResourceDictionary>
</ContentPage.Resources>
你看,我有各种各样的数据模板,每个都有自己的用途。头正在工作,其余的正在进行中
只有
我关心的是
实施。从单元到viewmodel,再通过数据模板。
现在这只是资源,这里是实际的页面UI(只有相关代码)
<ContentPage.Content>
... Content of the page, including the actual listview
<ListView
x:Name="ContactsListView"
HasUnevenRows="True""
ItemTemplate="{StaticResource TemplateSelector}"
ItemsSource="{Binding ListSource}">
</ListView>
</ContentPage.Content>
让我带你通过这个观点背后的逻辑之旅,在这个观点的viewmodel中。视图本身的代码不起任何作用,下面是该联系人列表的ViewModel。
public class ContactsViewModel : BaseViewModel, IContactsViewModel
{
readonly IContactsService _service;
List<object> _listSource;
public List<object> ListSource
{
get => _listSource;
private set
{
_listSource = value;
OnPropertyChanged();
}
}
public string CurrentText => "HelloX"; //<=== Important
readonly ISearchViewModel _searchViewModel;
readonly ICategoryFilterViewModel _categoryFilterViewModel;
readonly ISelectionViewModel _selectionViewModel;
public ContactsViewModel()
{
_service = new();
HeaderViewModel = new HeaderViewModel();
_searchViewModel = new();
_categoryFilterViewModel = new();
_selectionViewModel = new();
ListSource = GenerateDefaultList();
}
public async Task LoadContacts() //Called when UI appears.
{
await _service.LoadContacts();
var list = GenerateDefaultList();
list.AddRange(_service.Contacts);
ListSource = list;
}
List<object> GenerateDefaultList()
{
return new List<object>()
{
HeaderViewModel,
_searchViewModel, //<===== important
_categoryFilterViewModel,
_selectionViewModel
};
}
}
为了清晰起见,我包含了大部分代码;我想强调的重要一点是
ListSource
public class ContactDataTemplateSelector : DataTemplateSelector
{
public DataTemplate ContactTemplate { get; set; }
public DataTemplate HeaderTemplate { get; set; }
public DataTemplate SearchTemplate { get; set; }
public DataTemplate CategoryTemplate { get; set; }
public DataTemplate SelectionTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
switch (item)
{
case HeaderViewModel _:
return HeaderTemplate;
case SearchViewModel _:
return SearchTemplate; //<==== important
case CategoryFilterViewModel _:
return CategoryTemplate;
case SelectionViewModel _:
return SelectionTemplate;
default:
return ContactTemplate;
}
}
}
所以我有一个
SearchViewModel
if
声明。
这是在数据模板中使用的搜索单元格(它本身是通过数据模板选择器选择的)
<ViewCell x:Class="MYNAMESPACE.SearchCell">
<AbsoluteLayout>
<Frame>
<StackLayout>
<Entry
Placeholder="{Binding PlaceHolderText}"/>
<Button
Text="{Binding CurrentText}"
Command="{Binding SearchCommand}"/>
</StackLayout>
</Frame>
</AbsoluteLayout>
</ViewCell>
我尽可能多地删除了内容,而不冒着掩盖上下文的风险。我知道这是一堵代码墙,但我相信如果您决定进行调查,它会很有用。
CurrentText
. 我把它作为文本放在书里
搜索视图模型
public class SearchViewModel : ISearchViewModel
{
public string CurrentText => "<TODO SEARCH>"; //<=== Important
//NotifyPropertyChanged Implementation
}
我还有一个
当前文本
在里面
ContactsViewModel
搜索视图模型
. 我看到的是“”而不是“HelloX”。这就是我想要的。我只是不明白单元格如何/为什么使用我的viewmodel。
我只使用viewmodel来选择要显示的数据模板,而不将viewmodel设置为该数据模板的绑定上下文,也不使用viewcell。还是我?绑定上下文从何而来?