使用自定义TableView渲染器时,如何为TableSections设置不同的页脚

时间:2017-11-13 16:08:10

标签: xamarin xamarin.forms

我正在使用渲染器允许我在TableView中设置自定义页脚。渲染器有效,但我希望能够为不同的表格部分设置不同的页脚。例如,表格部分0的一个页脚和表格部分1的另一个页脚,一直到表格部分5。

这是我正在使用的XAML:

           <!-- <local:ExtFooterTableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">-->
                <TableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">
                <TableSection Title="Cards1">
                    <ViewCell Height="50">
                        <Label Text="Hello1" />
                    </ViewCell>
                    <ViewCell Height="50">
                        <Label Text="Hello2" />
                    </ViewCell>
                </TableSection>
                <TableSection Title="Cards2">
                    <TextCell Height="50" Text="Hello"></TextCell>
                </TableSection>

                </TableSection>
        <!--    </local:ExtFooterTableView>-->
            </TableView>

这里是C#类和渲染器:

public class ExtFooterTableView : TableView
{
    public ExtFooterTableView()
    {
    }
}

   using System;
using Japanese;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(ExtFooterTableView), typeof(Japanese.iOS.ExtFooterTableViewRenderer))]
namespace Japanese.iOS
{
    public class ExtFooterTableViewRenderer : TableViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
                return;

            var tableView = Control as UITableView;
            var formsTableView = Element as TableView;
            tableView.WeakDelegate = new CustomFooterTableViewModelRenderer(formsTableView);
        }


        private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
        {
            public CustomFooterTableViewModelRenderer(TableView model) : base(model)
            {
            }

            public override UIView GetViewForFooter(UITableView tableView, nint section)
            {
                Debug.WriteLine("xx");
                if (section == 0)
                {
                    return new UILabel()
                    {
                        // Text = TitleForFooter(tableView, section), // or use some other text here
                        Text = "abc",
                        TextAlignment = UITextAlignment.Left
                        // TextAlignment = NSTextAlignment.NSTextAlignmentJustified
                    };
                }
                else
                {
                    return new UILabel()
                    {
                        // Text = TitleForFooter(tableView, section), // or use some other text here
                        Text = "def",
                        TextAlignment = UITextAlignment.Left
                        // TextAlignment = NSTextAlignment.NSTextAlignmentJustified
                    };
                }
            }

        }
    }
}

代码有效但我想知道如何为XAML中的不同部分设置不同的页脚文本。像这样:

从我看到它看起来代码部分存在TitleForFooter(tableView, section)但我不知道如何使用它以及如何设置它。请注意,我并不是在寻找视图模型解决方案。我很乐意能够将部分页脚文本指定为TableView XAML的一部分。

如果有人能就此给我一些建议,我感激不尽。

2 个答案:

答案 0 :(得分:1)

很简单。您需要在CustomControl中将XAML的传递值的可绑定属性添加到CustomRenderer,如下所示:

Customer TableView

public class ExtFooterTableView : TableView
{
    public ExtFooterTableView()
    {
    }
}

Xaml控制代码

<local:ExtFooterTableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">

渲染器类

using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using yournamespace;
using System.ComponentModel;

[assembly: ExportRenderer(typeof(ExtFooterTableView), typeof(FooterTableViewRenderer))]
namespace yournamespace
{
    public class FooterTableViewRenderer : TableViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
        {
            base.OnElementChanged(e);
        }


        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            var view = (ExtFooterTableView)Element;

            if (e.PropertyName == ExtFooterTableView.IntentProperty.PropertyName)
            {
                string intent = view.Intent;
                // Do your stuff for intent property
            }

            if (e.PropertyName == ExtFooterTableView.HasUnevenRowsProperty.PropertyName)
            {
                bool hasUnevenRows = view.HasUnevenRows;
                // Do yout stuff for HasUnevenRow
            }
        }

    }
}

答案 1 :(得分:1)

首先,为了能够在XAML中指定部分页脚文本 - 最简单的选项是在TableSection中创建可绑定属性。但是当TableSection被封存时,我们无法派生它来定义我们的自定义可绑定属性。

因此,下一个选项是创建一个附加的可绑定属性。

public class Ex
{
    public static readonly BindableProperty FooterTextProperty =
        BindableProperty.CreateAttached("FooterText", typeof(string), typeof(Ex), defaultValue: default(string));

    public static string GetFooterText(BindableObject view)
    {
        return (string)view.GetValue(FooterTextProperty);
    }

    public static void SetFooterText(BindableObject view, string value)
    {
        view.SetValue(FooterTextProperty, value);
    }
}

下一步是更新渲染器以为每个部分检索此值:

private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
{
    public CustomFooterTableViewModelRenderer(TableView model) : base(model)
    {
    }

    public override UIView GetViewForFooter(UITableView tableView, nint section)
    {
        return new UILabel()
        {
            Text = TitleForFooter(tableView, section), // or use some other text here
            Font = UIFont.SystemFontOfSize(14),
            ShadowColor = Color.White.ToUIColor(),
            ShadowOffset = new CoreGraphics.CGSize(0, 1),
            TextColor = Color.DarkGray.ToUIColor(),
            BackgroundColor = Color.Transparent.ToUIColor(),
            Opaque = false,
            TextAlignment = UITextAlignment.Center
        };
    }

    //Retrieves the footer text for corresponding section through the attached property
    public override string TitleForFooter(UITableView tableView, nint section)
    {
        var tblSection = View.Root[(int)section];
        return Ex.GetFooterText(tblSection);
    }
}

样本用法

<local:ExtFooterTableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">
    <TableSection Title="Cards1" local:Ex.FooterText="Sample description">
        <ViewCell Height="50">
            <Label Margin="20,0,20,0" Text="Hello1" />
        </ViewCell>
        <ViewCell Height="50">
            <Label Margin="20,0,20,0" Text="Hello2" />
        </ViewCell>
    </TableSection>
    <TableSection  Title="Cards2" local:Ex.FooterText="Disclaimer note">
        <TextCell Height="50" Text="Hello"></TextCell>
    </TableSection>
</local:ExtFooterTableView>

enter image description here