【问题标题】:Alternating Row Colors in Xamarin Forms ListView IOSXamarin 表单 ListView IOS 中的交替行颜色
【发布时间】:2014-12-05 20:40:49
【问题描述】:

我正在尝试编写一个可以允许 ListView 具有交替行颜色的 CustomRenderer。我遇到了一个问题,不确定它是否可能是一个错误,或者我只是没有正确实现渲染器:

我对以下代码的期望是每个自定义视图单元格都应该根据其位置获得颜色。然而,这不是正在发生的事情,我相信这个代码tv.IndexPathForCell(cell).Row 应该返回单元格的索引,但它没有按预期工作。它当前正在返回一个空值(如果单元格不是部分视图,它应该返回),但我相信该单元格是表格视图的一部分,因此是我的问题。如果我注释掉var index = tv.IndexPathForCell(cell).Row;,然后将背景颜色设置为静态值,则代码和视图可以正常工作。此外,由于 null 值而引发异常,并且单元格设置为基础,并且视图以默认背景呈现。

我是不是做错了什么,我尝试了其他几件事,但我相信这应该是正确的方法。

c#代码:

[assembly: ExportRenderer(typeof(CustomViewCell), typeof(CustomViewCellRenderer))]


namespace AIM.iOS {

  class CustomViewCellRenderer : ViewCellRenderer {
    public override UITableViewCell GetCell(Cell item, UITableView tv) {
       UITableViewCell cell;

       try {
          cell = base.GetCell(item, tv);

          var customCell = (CustomViewCell)item;
          var cell = base.GetCell(item, tv);

          var index = tv.IndexPathForCell(cell).Row;

          cell.BackgroundColor = (index % 2 == 0) ? Color.Gray.ToUIColor() :
                                                  Color.White.ToUIColor();
       }catch (Exception ex){
          string message = ex.Message;
          cell = base.GetCell(item, tv);
       }

       return cell  
    }
  }
}

我正在从 Xamarin-Forms-Labs 扩展 ExtendedViewCell 类,它将背景属性添加到 ViewCell 对象。

namespace AIMUI.Controls {
  public class CustomViewCell : ExtendedViewCell {
    public CustomViewCell() { }
  }
}

这是 Xaml:

<localcontrols:ListView>
  <ListView.ItemTemplate>
    <DataTemplate>
      <localcontrols:CustomViewCell>
        <localcontrols:CustomViewCell.View>
        </localcontrols:CustomViewCell.View>
      </localcontrols:CustomViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</localcontrols:ListView>

编辑:

好的,所以我通过使用var index = tv.IndexPathForRowAtPoint(cell.Center).Row; 解决了获取索引的问题,但是这引起了另一个问题。它第一次完美运行,以及从子视图返回页面。但是,当我离开页面并从masterpage 转到另一个视图并返回时,它会将所有项目的背景设置为灰色。目前,我正在创建一个新页面,然后从菜单中将其设置为masterpage.details

【问题讨论】:

    标签: c# ios xamarin xamarin.forms custom-renderer


    【解决方案1】:

    这可以使用转换器而不是渲染器来完成。

    public class StripedBackgroundIndexConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || parameter == null) return Color.White;
            var index = ((ListView) parameter).ItemsSource.Cast<object>().ToList().IndexOf(value);
            return index % 2 == 0 ? Color.White : Color.FromRgb(240, 240, 240);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    然后命名您的 ListView 并使用 x:Reference 将其作为参数传递

    <ListView x:Name="MyItemsListView" ItemsSource="{Binding MyItems}" SelectedItem="{Binding SelectedMyItem, Mode=TwoWay}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <Grid BackgroundColor="{Binding .,Converter={StaticResource StripedBackgroundIndexConverter}, ConverterParameter={x:Reference MyItemsListView}}">
    
          </Grid>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
    

    当然,如果您需要自定义其他元素,您也可以在渲染器中使用转换器。

    【讨论】:

      【解决方案2】:

      您已经发现 IndexPathForRowAtPoint 将返回数据源中 Row 的索引即使该行不可见 ,不像 IndexPathForCell 在单元格可见之前无法正常工作。

      关于您的导航问题,当您将页面推送Xamarin.Forms 导航堆栈时,它们没有卸载并且仍然可以正常工作在幕后。这就是为什么当您再次浏览导航堆栈弹出时,您会看到与导航时完全相同相同的页面远离它(当然,除非您在 Page event-handlers 之一中有一些逻辑,这些逻辑将被重新调用以执行其他处理)。

      iOS 中,单元格在适当的时候被 EnqueuedDequeued,尽管它们不可见,但仍可能驻留在内存中,等待 垃圾收集

      当您离开页面(不是到子视图)然后返回该页面时,这听起来很奇怪的行为,由于 您正在使用的模数

      作为替代方案,仅出于探索和测试目的,将另一个字段引入您的 模型,该字段具有递增的 ID modulus 以设置行的背景颜色,看看您是否可以隔离 IndexPathForRowAtPoint 函数可能是主要问题所在。

      如果你能创建一个只有这个的小项目,对那些进一步协助的人会很有帮助吗?

      【讨论】:

        【解决方案3】:

        在联系 Xamarin 支持后,在他们的帮助下,这就是结果。

        indexPathForPoint 不可靠,具体取决于实际单元格在屏幕上的方式和时间。通常,GetCell 方法具有可靠的 NSIndexPath 参数,但 Forms 抽象不会传递此参数。

        建议作为增强功能HERE

        作为一种解决方法,您可以使用另一种方法进行索引。但是,这对我不起作用,因为它不是 100% 可靠的。我没有找到实现此功能的好方法。

        附注 - 我觉得这在 Xamarin 代码设计过程中被忽略了,简单地获取每个单元格的索引应该不难。

        【讨论】:

          猜你喜欢
          • 2016-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-21
          • 2011-10-13
          • 2018-06-25
          相关资源
          最近更新 更多