如何有条件地绑定TextCell Detail属性?

时间:2017-11-20 19:37:18

标签: c# android xamarin xamarin.ios xamarin.forms

在我正在研究的xamarin.forms安卓项目中,我有一个我希望在ListView中显示的对象列表。对象基于ClassA:

range(1,3)

注意ClassB对象的列表。 ClassB看起来像这样:

public class ClassA
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<ClassB> Types { get; set; }
}

我使用XAML部分工作,如下所示:

public class ClassB
{
    public string Type { get; set; }
    public int Count { get; set; }
}

问题是,根据ClassA.ClassB.Type属性的值,Detail属性的绑定需要针对每一行进行更改。例如。 if <TextCell Text="{Binding Name}" Detail="{Binding Types[0].Count }" Tapped="Cell_OnTapped" /> 那么Detail属性的TextCell绑定应为:

Types[0].Count > 0

如果Types[0].Count Types[0].Count > 0那么Detail属性的TextCell绑定应为:

Types[1].Count > 0

请注意,ClassA.Types中的项目不会超过三个。此外,ClassB.Count值都是预先计算的。

使用适用于Android的xamarin.forms,最好的方法是什么?

2 个答案:

答案 0 :(得分:0)

您可以像这样使用值转换器(注意:未经测试的代码!):

public class MyConverter : IValueConverter, IMarkupExtension
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (Equals(value,null))
                return string.Empty;

            var obj = (ClassA)value;

            // Your logic here to work out the string to display
            // NOTE: untested - may need to add null checks, etc.
            if (obj.Types[0].Count > 0 && obj.Types[1].Count > 0) 
            {
                return "type 1 count: " + Types[0].Count + "type 2: count: " Types[1].Count;
            }
            else if (obj.Types[0].Count > 0)
            {
                return Types[0].Count;
            }
            return string.Empty;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Only one way bindings are supported with this converter");
        }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }

然后在你的XAML中,像这样绑定:

<TextCell Text="{Binding Name}" Detail="{Binding ., Converter={converters:MyConverter} }" Tapped="Cell_OnTapped" />

答案 1 :(得分:0)

您可以通过两种不同的方法获得该结果。

1:ValueConverter。

直接绑定ClassA中的Types属性,并执行ValueConverter中显示内容的逻辑。有关此here的更多信息。

2:ViewModel

实现一个将由您ClassA对象组成的ViewModel。

拍摄你的模特

public class ClassA
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<ClassB> Types { get; set; }
}

public class ClassB
{
    public string Type { get; set; }
    public int Count { get; set; }
}

和您的要求,您可以实现类似下面的ViewModel:

public class ItemViewModel()
{
    public string Name { get; set; }

    public string Type { get; set; }

    public ItemViewModel(ClassA classA)
    {
        Name = classA.Name;

        if( classA.Types[0].Count > 0 )
        {
            Type = $"{classA.Types[0].Count}";
        }
        else if (classA.Types[0].Count > 0 && classA.Types[1].Count > 0)
        {
            Type = $"type 1 count: {Types[0].Count} type 2: count: {Types[1].Count}";
        }
    }
}

使用Linq,您可以将List项目转换为ViewModel项目的新列表。

List<ClassA> Items = ......

var ItemVm = Items.Select(a => New ItemViewModel(a)).ToList();

使用ItemVm将其绑定到您的视图。

希望这会有所帮助.-

注意:我没有对类型列表进行任何验证,但我鼓励你这样做。

注意2:您可能还需要在ViewModel中实现INotifyPropertyChanged。