【问题标题】:Change background color selecteditem Listview更改背景颜色选定项列表视图
【发布时间】:2016-01-15 04:04:08
【问题描述】:

我对 Xamarin.Forms 中的列表视图有疑问 成功地将我的列表视图与某些项目绑定,但我想更改所选单元格的背景颜色如何在 Xamarin.Forms 中执行此操作

我利用

var cell = DataTemplate(typeof(ImageCell));

ListView listView = new ListView
{
    SeparatorColor = Color.Green,
    ItemsSource = ListlvData,
    ItemTemplate = cell, // Set the ImageCell to the item templatefor the listview
};

【问题讨论】:

标签: c# xamarin.forms


【解决方案1】:

编辑 2:

如果我遇到奇怪的问题,我的ViewCellBackgroundColor 永远不会变回原来的颜色,所以我开始这样做来改变颜色:

cell.Tapped += async (sender, args) => {
    cell.View.BackgroundColor = Color.Red;

#pragma warning disable 4014 //These pragma's are only needed if your Tapped is being assigned an async anonymous function and muffles the compiler warning that you did not await Task.Run() which you do not want to fire and forget it

    Task.Run(async () => {     //Change the background color back after a small delay, no matter what happens
        await Task.Delay(300); //Or how ever long to wait

        Device.BeginInvokeOnMainThread(() => cell.View.BackgroundColor = Color.Default); //Turn it back to the default color after your event code is done
    });

#pragma warning restore 4014

    await OnListViewTextCellTapped(cell); //Run your actual `Tapped` event code

};

编辑:

要将以下代码添加到ListView.DataTemplate,您需要执行以下操作:

ListView listView = new ListView {
    SeparatorColor = Color.Green,
    ItemsSource    = ListlvData
};

listView.ItemTemplate = new DataTemplate(() => {
    ViewCell cell = new ViewCell();

    cell.Tapped += (sender, args) => {
        cell.View.BackgroundColor = Color.Red;
        OnListViewTextCellTapped(cell);            //Run your actual `Tapped` event code
        cell.View.BackgroundColor = Color.Default; //Turn it back to the default color after your event code is done
    };

    cell.View = new Image();

    return cell;
});

要更改Tapped 的背景颜色,您需要在其中使用ViewCellImage 控件,因为ImageCell 默认不支持BackgroundColors。

我在ViewCell 中添加了一个StackLayout,但随后在Tapped 事件中,我更改了ViewCell.ViewBackgroundColor,如下所示:

ViewCell cell = new ViewCell();

cell.Tapped += (sender, args) => {
    cell.View.BackgroundColor = Color.Red;
    OnListViewTextCellTapped(cell);            //Run your actual `Tapped` event code
    cell.View.BackgroundColor = Color.Default; //Turn it back to the default color after your event code is done
};

【讨论】:

  • 我如何将它添加到 DataTemplateLayout
  • 很高兴我能帮上忙。
【解决方案2】:

我知道这个问题在很久以前就已经得到了回答,但我想我会在这里为任何可能偶然发现这个问题的人添加更多信息,以寻找一种对 MVVM 更友好的方式来执行此操作。我最终得到了以下内容,如果他们愿意的话,希望有人会觉得有用。

您将需要一个值转换器,如下所示:

public class UseColorIfConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? parameter : Color.Transparent;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

如果提供的参数计算结果为真,转换器只会返回适当的Color。我还在我的 App.xaml 中将此转换器注册为静态资源(必须手动创建),即:

<?xml version="1.0" encoding="utf-8" ?>
<forms:FormsApplication xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:forms="clr-namespace:Caliburn.Micro.Xamarin.Forms;assembly=Caliburn.Micro.Platform.Xamarin.Forms"
         x:Class="Path.To.Application.App"
         xmlns:converters="clr-namespace:Path.To.Converters.Namespace;assembly=Converter.Assembly">
    <Application.Resources>
         <converters:UseColorIfConverter x:Key="UseColorIf"></converters:UseColorIfConverter>
    </Application.Resources>
</forms:FormsApplication>

请注意,我使用的是 Caliburn Micro,但同样适用于默认的 Xamarin.Forms.Application 类。

转换器和潜在绑定的用法如下:

<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ContentView BackgroundColor="{Binding Path=Selected, Converter={StaticResource UseColorIf}, ConverterParameter={x:StaticResource ListSelectionColor}}" ...>
                    <!--Display-->
                </ContentView>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

然后,这允许您绑定每个视图模型中的一个属性,该属性指示它是否被选中。该属性必须保持同步,但很容易通过订阅属性更改事件来完成,例如:

public class MenuViewModel : Screen
{
    public BindableCollection<SectionViewModel> Items { get; }    

    public MenuViewModel(IEnumerable<SectionViewModel> sections)
    {
        Items = new BindableCollection<SectionViewModel>(sections);
        PropertyChanged += OnPropertyChanged;
    }

    private SectionViewModel _selectedItem;

    public SectionViewModel SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            if (_selectedItem == value)
                return;
            _selectedItem = value;
            NotifyOfPropertyChange(nameof(SelectedItem));
        }
    }

    private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
    {
        if (propertyChangedEventArgs.PropertyName == nameof(SelectedItem))
        {
            foreach (var item in Items)
            {
                item.Selected = item == SelectedItem;
            }
        }
    }
}

在这样做之后还有一件琐碎的事情,那就是每个平台上使用的默认渲染器。我还没有检查过 Android,但至少在 IOS 上,您仍然会看到灰色边框,因此以下内容只是将其删除:

using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(ViewCell), typeof(CustomListViewCellRenderer))]

namespace My.Awesome.Ios.Client.Renderers
{
    class CustomListViewCellRenderer : ViewCellRenderer
    {

        public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
        {
            var cell = base.GetCell(item, reusableCell, tv);

            cell.SelectionStyle = UITableViewCellSelectionStyle.None;
            return cell;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2013-06-24
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多