2014-10-10 5 views
2

Я пытаюсь написать CustomRenderer, который может позволить ListView иметь переменные цвета строк. Я столкнулся с проблемами и не уверен, может ли это быть ошибкой или я просто не выполняю рендеринг правильно:Чередование строк в Xamarin Forms ListView IOS

Мои ожидания в отношении следующего кода заключаются в том, что каждая пользовательская ячейка зрения должна получать цвет на основе его позиции , Однако это не то, что происходит, я считаю, что этот код tv.IndexPathForCell(cell).Row должен вернуть индекс ячейки, но он не работает должным образом. В настоящее время он возвращает нулевое значение (которое должно быть, если ячейка не отображается в части), но я считаю, что ячейка является частью представления таблицы и, следовательно, моей проблемой. Если я прокомментирую var index = tv.IndexPathForCell(cell).Row;, а затем установите цвет фона в статичное значение, код и представление будут работать правильно. Кроме того, исключение вызывается из-за нулевого значения, и ячейка устанавливается в базу, а представление отображается с фоном по умолчанию.

Я делаю что-то неправильно, я пробовал несколько других вещей, но я считаю, что это должен быть правильный способ сделать это.

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 
    } 
    } 
} 

Я расширив класс ExtendedViewCell от Xamarin-форм-Labs, который добавляет свойства фона для объекта 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> 

Edit:

Итак, я решил вопрос с получением индекс с помощью var index = tv.IndexPathForRowAtPoint(cell.Center).Row;, однако это вызвало еще один вопрос. Он работает отлично в первый раз, а также возвращается на страницу из подвид. Однако, когда я покидаю страницу и перехожу к другому виду из masterpage и возвращаюсь, он устанавливает фон всех элементов серым. В настоящее время я создаю новую страницу, а затем устанавливаю ее на masterpage.details, когда вы выходите из меню.

ответ

0

После контакта с Xamarin Support, и с их помощью это стало результатом.

indexPathForPoint не является надежным в зависимости от того, как и когда фактическая ячейка находится на экране. Как правило, метод GetCell имеет параметр NSIndexPath, который является надежным, но абстракция форм не проходит это.

Отдается аксессуаром HERE

В качестве обходного пути, вы можете использовать другой метод для индекса. Однако это не сработало для меня, поскольку оно не было на 100% надежным. Я не нашел отличный способ реализовать эту функциональность.

В качестве примечания стороны - Я чувствую, что все это было рассмотрено в процессе разработки кода Xamarin. Не так сложно просто получить индекс каждой ячейки.

1

Как вы уже выяснили IndexPathForRowAtPoint возвращает индекс Row в источнике данных даже если строка не видна, в отличие от IndexPathForCell, что не будет работать корректно, пока клетки видно.

Что касается навигационного вопроса, когда вы Нажмите страниц на Xamarin.Forms Navigation Stack они не разгружается и до сих пор функционируют за кулисами. Вот почему, когда вы переходите через Навигационный стек и Поп один раз, вы видите ту же самую страницу точно так же, как вы проехали от нее (если, конечно, у вас нет логики в одном из Страницаобработчики событий, которые будут повторно вызваны, выполняя что-то другое).

В прошивке клетка и поставлена ​​в очереди из очереди, когда это необходимо, и все еще может находиться в памяти, хотя они не видны, в ожидании Garbage Collection.

Это звучит очень странное поведение, что, когда вы уйдете со страницы (не в подвид), а затем вернуться на эту страницу, что он не работает, в связи с модуля, что вы используете ,

В качестве альтернативы, только для разведки и тестирования, ввести еще одно поле в вашей модели, которая имеет большее ID что вы делаете модуль на, чтобы установить цвет фона в ряду, чтобы узнать, можете ли вы выделитьIndexPathForRowAtPoint функция, возможно, где основная проблема.

Если вы можете создать небольшой проект только с этим, это будет очень полезно для тех, кто помогает дальше?

2

Это можно сделать с помощью конвертера вместо средства визуализации.

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 и передать его в качестве параметра с помощью х: Ссылка

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

Конечно, вы можете также использовать конвертер в видеообработки, если вы необходимости настроить другие элементы.

Смежные вопросы