更改背景颜色selecteditem Listview

Ste*_*hot 4 c# xamarin.forms

我有一个关于Xamarin.list中的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
};
Run Code Online (Sandbox Code Playgroud)

hva*_*an3 7

编辑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

};
Run Code Online (Sandbox Code Playgroud)

编辑:

要将以下代码添加到a 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;
});
Run Code Online (Sandbox Code Playgroud)

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

我把一个StackLayout内部的ViewCell,但随后的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
};
Run Code Online (Sandbox Code Playgroud)


小智 6

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

Color如果提供的参数的计算结果为true,则转换器只返回相应的值.我还在我的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>
Run Code Online (Sandbox Code Playgroud)

请注意我使用的是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>
Run Code Online (Sandbox Code Playgroud)

然后,这允许您绑定每个视图模型中的属性,该属性指示是否选中它.此属性必须保持同步,但通过订阅属性更改事件可以轻松完成,例如:

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

执行此操作后还有一个琐碎的事情,那就是每个平台上使用的默认渲染器.我还没有检查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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)