问题描述
我对Xamarin还是陌生的,因此制作的应用程序将包含一系列项目,我希望可以选择将其喜欢/设置为喜欢的功能。
但是由于ListView中的x Name,访问图像视图和按钮视图x名称时出现上下文问题。我尝试过的是有一个foreach循环,通过将ListView,Button和Image分成不同的网格行来获取与ListView中的项目一样多的图像和按钮。 令人遗憾的是,导致Listview正常填充,但是仅显示一幅图像和一个按钮。
这是我尝试过的: 我的Xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converters="clr-namespace:MyApp.Converters"
x:Class="MyApp.MainPage">
<StackLayout Orientation="Horizontal" HorizontalOptions="CenterandExpand">
<Grid>
<ListView
x:Name="CategoryList"
SelectionMode="None"
ItemsSource="{Binding FavCategories}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Grid.Column="0" Text="{Binding .,Converter{converters:toupperConverter}}"></Label>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Image x:Name="ImgFav"
Grid.Column="2"
Source="{Binding IsFav}"></Image>
<Button x:Name="BtnFav"
Grid.Column="3"
Text="{Binding Favstate}"
Clicked="BtnFav_Clicked"></Button>
</Grid>
</StackLayout>
</ContentPage>
我的C#:
public async Task Load()
{
ApiService apiService = new ApiService();
Categories.Clear();
List<FavCategoryModel> favCategories = new List<FavCategoryModel>();
var categories = await apiService.GetCategories();
foreach (var category in categories)
{
Categories.Add(category);
}
foreach(var item in Categories)
{
favCategories.Add(new FavCategoryModel { Category = item,IsFavourite = false });
}
CategoryList.ItemsSource = favCategories.Select(c =>c.Category.ToString()).ToList();
var isFavourite = favCategories.Select(f => f.IsFavourite);
foreach(var isfav in favCategories)
{
if (favCategories.Any(f => f.IsFavourite) == false)
{
foreach(var category in categories)
{
ImgFav.source = "nonFav.Png";
BtnFav.Text = "Like";
}
}
}
因此,我知道我是否正确,如果按钮和图像位于ListView内,则应该能够操作它们,并在那里找到与填充列表的类别相对应的行。 像这样:
<ListView
x:Name="CategoryList"
SelectionMode="None"
ItemsSource="{Binding FavCategories}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Grid.Column="0" Text="{Binding .,Converter{converters:toupperConverter}}"></Label>
<Image x:Name="ImgFav"
Grid.Column="2"
Source="{Binding IsFav}"></Image>
<Button x:Name="BtnFav"
Grid.Column="3"
Text="{Binding Favstate}"
Clicked="BtnFav_Clicked"></Button>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
但是导致按钮和图像的x名称在当前上下文中不存在。 有人有什么智慧可以帮助我克服这个障碍吗?
谢谢!
解决方法
看看 MVVM ,您会更清楚地了解设计。使用绑定ViewMode时,我们不建议直接处理Control。此外,如果使用DataTemplate
,我们也将不会获得x:Name
的控制权。
不必担心如何获得控件的x:Name
,只需专注于要实现的功能即可。它将使用MVVM来实现所需的功能。
例如,我的Xaml代码如下:
<ListView x:Name="MyListView"
HasUnevenRows="True"
RowHeight="150"
CachingStrategy="RecycleElement"
ItemSelected="MyListView_ItemSelected"
ItemsSource="{Binding myItems}"
IsVisible="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal"
VerticalOptions="Center">
<Label Text="Hello World"
HorizontalOptions="StartAndExpand"></Label>
<Label Text="{Binding Address}"
HorizontalOptions="CenterAndExpand"></Label>
<Label Text="{Binding eMail}"
HorizontalOptions="CenterAndExpand"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
然后,我将编写以下代码,以显示我的需求:
public PageListView()
{
InitializeComponent();
var myItems = new List<Contacts>();
myItems.Add(new Contacts() {Address="1",eMail="1" });
myItems.Add(new Contacts() { Address = "2",eMail = "2" });
myItems.Add(new Contacts() { Address = "3",eMail = "3" });
myItems.Add(new Contacts() { Address = "4",eMail = "4" });
myItems.Add(new Contacts() { Address = "5",eMail = "5" });
this.BindingContext = this;
}
Contacts.cs
:
public class Contacts
{
public string Address { get; set; }
public string eMail { get; set; }
}
效果:
==================================更新============ ==================
如果需要默认值,请define a fallback value。
<Label Text="{Binding Address,FallbackValue='Address unknown'}"
... />
然后从rest api设置ItemSource
,这里是the sample。
protected async override void OnAppearing ()
{
base.OnAppearing ();
listView.ItemsSource = await App.TodoManager.GetTasksAsync ();
}