更改背景颜色selecteditem Listview

时间:2015-10-16 11:52:41

标签: c# xamarin.forms

我对Xamarin.Forms中的listview有疑问 使用一些项目成功地将我的列表视图绑定,但我想更改所选单元格的背景颜色如何在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
};

2 个答案:

答案 0 :(得分:7)

编辑2:

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

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不支持BackgroundColor s默认情况下。

我在StackLayout中加了一个ViewCell,但在Tapped事件中,我更改了ViewCell.View' s BackgroundColor,就像这样:

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

答案 1 :(得分:5)

我知道这已经在很久以前得到了解答,但我想在这里添加更多信息可供任何可能偶然发现这个问题的人寻找更加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();
    }
}

如果提供的参数的计算结果为true,则转换器只返回相应的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;
        }
    }
}