Xamarin Forms 更改 ListView 中每个 ViewCell 的背景颜色
Xamarin Forms Changing background color of each ViewCell in ListView
我在 listView 中有预订时间,例如 8:00、9:00 等。通过 JSON,我从远程数据库中检索已经完成的预订。所以我想将每个单元格(标签)的背景颜色更改为保留的红色,其余为绿色(免费预约)。
这是我的 xaml 代码:
<StackLayout>
<ListView x:Name="ItemsListView"
ItemsSource="{Binding Items}"
VerticalOptions="FillAndExpand"
HasUnevenRows="true"
RefreshCommand="{Binding LoadItemsCommand}"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
CachingStrategy="RecycleElement"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding Text}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
ListView 由如下模型填充:
new Termin { Id = Guid.NewGuid().ToString(), Text = "12:00", Description="" },
那么如何更改这些单元格的颜色?
我想要的伪代码:
for(int i=0; i< number of items in the listview; i++) {
if(reservations.contains(listview.itemAt(i)) {
//change background color of viewcell (label?) at position i
}
}
(正如布鲁诺评论的那样)
向模型添加 IsReserved
布尔值 属性:
public class Termin
{
public string Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public bool IsReserved { get; set; }
}
IValueConverter
即 returns Red
如果 IsReserved
为真:
public class IsReservedToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value ? Color.Red : Color.Transparent);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
添加 IValueConverter 的命名空间:
xmlns:local="clr-namespace:SameNameSpace;assembly=SomeAssemblyName"
将 IValueConverter 添加到您的 ContentPage.Resources
<ContentPage.Resources>
<ResourceDictionary>
<local:IsReservedToColorConverter x:Key="IsReservedToColor"></local:IsReservedToColorConverter>
</ResourceDictionary>
</ContentPage.Resources>
在您的绑定中使用转换器
<Frame BackgroundColor = "{Binding IsReserved, Converter={StaticResource IsReservedToColor}}">
最终 XAML 示例:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Forms_31_1.ListPage"
xmlns:local="clr-namespace:Forms_31_1;assembly=Forms_31_1" >
<ContentPage.Resources>
<ResourceDictionary>
<local:IsReservedToColorConverter x:Key="IsReservedToColor"></local:IsReservedToColorConverter>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<ListView x:Name="listView" BackgroundColor="Aqua" SeparatorColor="Red">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame BackgroundColor = "{Binding IsReserved, Converter={StaticResource IsReservedToColor}}">
<StackLayout Orientation="Vertical">
<Label Text="{Binding Text}" />
<Label Text="{Binding Description}" />
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
输出:
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "11:00" });
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "12:00", IsReserved = true });
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "13:00" });
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "14:00" });
您可以使用自定义视图单元格。我在我的项目中编写了一个自定义视图单元格并使用 XFGloss(XFGloss 是 Xamarin.Forms 项目的附加组件,它向标准 XF 页面和控件添加新属性 类)来制作 listView 的行丰富多彩的。你的 listView 不会失去 XFGloss 的触觉反馈。我使用的自定义 viewCell 是:
public class MyViewCell : ViewCell
{
private Color BackgroundColor
{
get => CellGloss.GetBackgroundColor(this);
set => CellGloss.SetBackgroundColor(this, value);
}
public Color EvenColor { get; set; }
public Color UnevenColor { get; set; }
protected override void OnAppearing()
{
base.OnAppearing();
if (!(Parent is ListView listView))
throw new Exception(
$"The Binding Context is not {typeof(ListView)}. This component works only with {typeof(ListView)}.");
int index;
if (listView.IsGroupingEnabled)
{
index = listView.TemplatedItems.GetGroupAndIndexOfItem(BindingContext).Item2;
}
else
{
index = listView.TemplatedItems.IndexOf(this);
}
if (index != -1)
BackgroundColor = index % 2 == 0 ? EvenColor : UnevenColor;
}
}
它在 xaml 文件中的用法很简单,如下所示:
<components:MyViewCell EvenColor="White" UnevenColor="#eeeeee">
我在 listView 中有预订时间,例如 8:00、9:00 等。通过 JSON,我从远程数据库中检索已经完成的预订。所以我想将每个单元格(标签)的背景颜色更改为保留的红色,其余为绿色(免费预约)。
这是我的 xaml 代码:
<StackLayout>
<ListView x:Name="ItemsListView"
ItemsSource="{Binding Items}"
VerticalOptions="FillAndExpand"
HasUnevenRows="true"
RefreshCommand="{Binding LoadItemsCommand}"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
CachingStrategy="RecycleElement"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding Text}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
ListView 由如下模型填充:
new Termin { Id = Guid.NewGuid().ToString(), Text = "12:00", Description="" },
那么如何更改这些单元格的颜色?
我想要的伪代码:
for(int i=0; i< number of items in the listview; i++) {
if(reservations.contains(listview.itemAt(i)) {
//change background color of viewcell (label?) at position i
}
}
(正如布鲁诺评论的那样)
向模型添加 IsReserved
布尔值 属性:
public class Termin
{
public string Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public bool IsReserved { get; set; }
}
IValueConverter
即 returns Red
如果 IsReserved
为真:
public class IsReservedToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value ? Color.Red : Color.Transparent);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
添加 IValueConverter 的命名空间:
xmlns:local="clr-namespace:SameNameSpace;assembly=SomeAssemblyName"
将 IValueConverter 添加到您的 ContentPage.Resources
<ContentPage.Resources>
<ResourceDictionary>
<local:IsReservedToColorConverter x:Key="IsReservedToColor"></local:IsReservedToColorConverter>
</ResourceDictionary>
</ContentPage.Resources>
在您的绑定中使用转换器
<Frame BackgroundColor = "{Binding IsReserved, Converter={StaticResource IsReservedToColor}}">
最终 XAML 示例:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Forms_31_1.ListPage"
xmlns:local="clr-namespace:Forms_31_1;assembly=Forms_31_1" >
<ContentPage.Resources>
<ResourceDictionary>
<local:IsReservedToColorConverter x:Key="IsReservedToColor"></local:IsReservedToColorConverter>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<ListView x:Name="listView" BackgroundColor="Aqua" SeparatorColor="Red">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame BackgroundColor = "{Binding IsReserved, Converter={StaticResource IsReservedToColor}}">
<StackLayout Orientation="Vertical">
<Label Text="{Binding Text}" />
<Label Text="{Binding Description}" />
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
输出:
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "11:00" });
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "12:00", IsReserved = true });
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "13:00" });
posts.Add(new Termin { Id = Guid.NewGuid().ToString(), Text = "14:00" });
您可以使用自定义视图单元格。我在我的项目中编写了一个自定义视图单元格并使用 XFGloss(XFGloss 是 Xamarin.Forms 项目的附加组件,它向标准 XF 页面和控件添加新属性 类)来制作 listView 的行丰富多彩的。你的 listView 不会失去 XFGloss 的触觉反馈。我使用的自定义 viewCell 是:
public class MyViewCell : ViewCell
{
private Color BackgroundColor
{
get => CellGloss.GetBackgroundColor(this);
set => CellGloss.SetBackgroundColor(this, value);
}
public Color EvenColor { get; set; }
public Color UnevenColor { get; set; }
protected override void OnAppearing()
{
base.OnAppearing();
if (!(Parent is ListView listView))
throw new Exception(
$"The Binding Context is not {typeof(ListView)}. This component works only with {typeof(ListView)}.");
int index;
if (listView.IsGroupingEnabled)
{
index = listView.TemplatedItems.GetGroupAndIndexOfItem(BindingContext).Item2;
}
else
{
index = listView.TemplatedItems.IndexOf(this);
}
if (index != -1)
BackgroundColor = index % 2 == 0 ? EvenColor : UnevenColor;
}
}
它在 xaml 文件中的用法很简单,如下所示:
<components:MyViewCell EvenColor="White" UnevenColor="#eeeeee">