我知道这个问题已经有一段时间没有得到解答了,但我想为那些寻找更加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="" SelectedItem="">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView BackgroundColor=", ConverterParameter=}" ...>
<!--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;
}
}
}