2

ListView が行の色を交互にできるようにする CustomRenderer を作成しようとしています。問題が発生しましたが、それがバグなのか、レンダラーを正しく実装していないだけなのかわかりません。

次のコードに対する私の期待は、各カスタム ビュー セルがその位置に基づいて色を取得することです。ただし、これは起こっていることではありません。このコードtv.IndexPathForCell(cell).Rowはセルのインデックスを返す必要があると思いますが、期待どおりに機能していません。現在、null値を返しています(セルが一部のビューではない場合はそうなるはずです)が、セルがテーブルビューの一部であるため、私の問題であると考えています。コメントアウトしてから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  
    }
  }
}

ViewCell オブジェクトにバックグラウンド プロパティを追加する Xamarin-Forms-Labs から ExtendedViewCell クラスを拡張しています。

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、メニューから来たときにそれを に設定しています。

4

3 に答える 3

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 に名前を付け、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>

もちろん、他の要素をカスタマイズする必要がある場合は、レンダラーでコンバーターを使用することもできます。

于 2016-02-23T21:19:41.647 に答える
0

Xamarin サポートに連絡した後、彼らの助けを借りて、これが結果でした。

indexPathForPoint は、実際のセルが画面上にある方法とタイミングに基づいて信頼できません。通常、GetCell メソッドには信頼できる NSIndexPath パラメータがありますが、フォームの抽象化ではこれが渡されません。

拡張機能として提案HERE

回避策として、インデックスに別の方法を使用できます。ただし、100%信頼できるわけではないため、これはうまくいきませんでした。この機能を実装する優れた方法が見つかりませんでした。

余談ですが、これは Xamarin のコード設計プロセスで見過ごされているように感じます。各セルのインデックスを単純に取得するのはそれほど難しいことではありません。

于 2014-10-15T14:53:46.360 に答える