【问题标题】:Xamarin Forms Changing background color of each ViewCell in ListViewXamarin Forms更改ListView中每个ViewCell的背景颜色
【发布时间】:2019-06-20 03:05:50
【问题描述】:

我在 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 属性会更容易。之后,在 Listview viewcell 中只有一个转换器来改变颜色,例如。
  • 我太新手了,听不懂你说的一半。

标签: listview xamarin xamarin.forms background-color


【解决方案1】:

(正如布鲁诺评论的那样)

为您的模型添加 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 如果IsReserved 为真,则返回Red

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" });

【讨论】:

  • 感谢您的详细回答,您的代码显然有效。
  • @ChrisFodor 很高兴它有帮助 ?
  • 有什么方法可以代替使用 IvalueConverter 分配颜色只是将其作为参数传递?例如 = IsReserved=true,color red;.To 能够将不同的颜色传递给框架?
  • @Pxaml 当然,您可以为属性分配实际颜色(Color.Red 等)或使用绑定参数并传递颜色:docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…
【解决方案2】:

您可以使用自定义视图单元格。我在我的项目中编写了一个自定义视图单元格并使用 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">

【讨论】:

    猜你喜欢
    • 2017-10-03
    • 1970-01-01
    • 2021-03-19
    • 2019-09-09
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多