

cell.SelectionStyle的颜色。
此示例是将点击的项目颜色设置为透明。
如果您希望,可以使用UITableViewCellSelectionStyle中的其他颜色进行更改。这需要在Forms项目中创建一个新的自定义ListView渲染器,并在平台项目中编写。
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Control == null)
{
return;
}
if (e.PropertyName == "ItemsSource")
{
foreach (var cell in Control.VisibleCells)
{
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
}
}
}
}
对于Android,您可以在values/styles.xml中添加此样式。
<style name="ListViewStyle.Light" parent="android:style/Widget.ListView">
<item name="android:listSelector">@android:color/transparent</item>
<item name="android:cacheColorHint">@android:color/transparent</item>
</style>
e.PropertyName == "ItemsSource"更改为e.PropertyName == "SelectedItem"才能使其正常工作。 - ScuzzlebuttUITableViewCellSelectionStyle仅提到了两种内置的颜色,蓝色和灰色。 - ToolmakerStevelistView = new ListView() { ... };但是如果你这样做,它就无法工作(所选项目的背景仍然是灰色的):listView = new ListView(cachingStrategy:ListViewCachingStrategy.RecycleElement) { ... };
下面是一个即使使用非标准的cachingStrategy也能正常工作的解决方案。我更喜欢这种解决方案,而不是在OnItemSelected方法中编写代码并将背景颜色与ViewModel进行绑定。
感谢@Lang_tu_bi_dien在这里发布了这个想法:Listview Selected Item Background Color
最终代码如下:
Xamarin.Forms 代码:
namespace MyProject
{
public class ListView2 : ListView
{
public ListView2(ListViewCachingStrategy cachingStrategy) : base(cachingStrategy)
{
}
}
}
在您的页面上使用XAML:
<ListView2 x:Name="myListView" ListViewCachingStrategy="RecycleElement" ItemsSource="{Binding ListSource}" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Label Text="{Binding Name}" HorizontalOptions="Center" TextColor="White" />
</ContentView>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView2>
[assembly: ExportRenderer(typeof(ListView2), typeof(ListView2Renderer))]
namespace MyProject.iOS
{
public partial class ListView2Renderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Control != null && e != null)
{
//oldDelegate = (UITableViewSource)Control.Delegate;
Control.Delegate = new ListView2Delegate(e.NewElement);
}
}
}
class ListView2Delegate : UITableViewDelegate
{
private ListView _listView;
internal ListView2Delegate(ListView listView)
{
_listView = listView;
}
public override void WillDisplay(UITableView tableView, UITableViewCell cell, Foundation.NSIndexPath indexPath)
{
cell.SelectedBackgroundView = new UIView()
{
BackgroundColor = Color.Red.ToUIColor()
};
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_listView = null;
}
base.Dispose(disposing);
}
}
}
注意:由于您替换了默认委托,可能会遇到一些问题,请参见在自定义渲染器中设置控件的委托会导致功能丢失以获取更多信息。在我的项目中,如果我这样做,一切都能正常工作:
对于使用默认缓存策略ListViewCachingStrategy.RetainElement的ListViews,请使用普通的ListView和此线程中提供的ListItemViewCellRenderer代码。
对于使用非默认缓存策略(即ListViewCachingStrategy.RecycleElement或ListViewCachingStrategy.RecycleElementAndDataTemplate)的ListViews,请使用此ListView2。
我还向Xamarin提交了一个功能请求,请投票支持它,如果您认为应将其添加到标准ListView中:ListView迫切需要SelectedItemBackgroundColor属性
@android:color/transparent
改变选择颜色的最简单方法是将以下内容添加到您的Android.Resources.values.styles中
<item name="android:colorPressedHighlight">@android:color/holo_blue_bright</item>
<item name="android:colorFocusedHighlight">@android:color/holo_blue_bright</item>
<item name="android:colorActivatedHighlight">@android:color/holo_blue_bright</item>
ListView的功能。然后可以使用它来根据需要以任何方式更改所选项目。可以修改颜色,根据所选状态显示或隐藏单元格的不同部分。
让我们向我们的ViewCell添加一个IsSelected属性。无需将其添加到数据对象中;listview选择单元格而不是绑定数据。
public partial class SelectableCell : ViewCell {
public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(SelectableCell), false, propertyChanged: OnIsSelectedPropertyChanged);
public bool IsSelected {
get => (bool)GetValue(IsSelectedProperty);
set => SetValue(IsSelectedProperty, value);
}
// You can omit this if you only want to use IsSelected via binding in XAML
private static void OnIsSelectedPropertyChanged(BindableObject bindable, object oldValue, object newValue) {
var cell = ((SelectableCell)bindable);
// change color, visibility, whatever depending on (bool)newValue
}
// ...
}
为了在列表视图中创建单元格和选择之间的缺失链接,我们需要一个转换器(最初的想法来自Xamarin论坛):
public class IsSelectedConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value != null && value == ((ViewCell)parameter).View.BindingContext;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
我们使用这个转换器将两者连接起来:
<ListView x:Name="ListViewName">
<ListView.ItemTemplate>
<DataTemplate>
<local:SelectableCell x:Name="ListViewCell"
IsSelected="{Binding SelectedItem, Source={x:Reference ListViewName}, Converter={StaticResource IsSelectedConverter}, ConverterParameter={x:Reference ListViewCell}}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这个相对复杂的绑定用于检查当前选中的实际项。它将列表视图的SelectedItem属性与单元格中视图的BindingContext进行比较。该绑定上下文是我们实际绑定到的数据对象。换句话说,它检查SelectedItem指向的数据对象是否实际上是单元格中的数据对象。如果它们相同,我们就有了选定的单元格。我们将其绑定到IsSelected属性中,然后可以在XAML或代码后台中使用它来查看视图单元格是否处于选定状态。
只有一个注意点:如果您想在页面显示时设置默认选定项,您需要聪明一些。不幸的是,Xamarin Forms没有页面显示事件,我们只有出现事件,这对于设置默认值来说太早了:绑定不会被执行。所以,使用一点延迟:
protected override async void OnAppearing() {
base.OnAppearing();
Device.BeginInvokeOnMainThread(async () => {
await Task.Delay(100);
ListViewName.SelectedItem = ...;
});
}
OnAppeared方法,需要每个平台的自定义渲染器来实现这样的方法,或者正如答案中所示,需要延迟操作的hack。我同意延迟hack很糟糕;事实上,即使在快速设备上,对于更复杂的页面,它也必须增加!(希望Maui最终能够添加OnAppeared。) - ToolmakerStevepublic class ListViewRenderer : Xamarin.Forms.Platform.iOS.ListViewRenderer
{
public ListViewRenderer()
{
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
var controller = this.ViewController as UITableViewController;
if (controller != null)
{
var tableView = controller.TableView;
if (tableView != null && tableView.Subviews != null)
{
//For lower iOS version, this line must add, otherwise it can not find any UITableViewCell
tableView.LayoutSubviews();
var backgroundColor = Color.Red.ToUIColor();
foreach (var subview in tableView.Subviews)
{
if (subview is UITableViewCell tableViewCell)
{
tableViewCell.SelectedBackgroundView = new UIView
{
BackgroundColor = backgroundColor
};
tableViewCell.MultipleSelectionBackgroundView = new UIView
{
BackgroundColor = backgroundColor
};
}
}
}
}
}
}