【问题标题】:How can I set up different footers for TableSections when using a Custom TableView Renderer使用自定义 TableView 渲染器时如何为 TableSections 设置不同的页脚
【发布时间】:2017-11-16 16:07:35
【问题描述】:

我正在使用渲染器来允许我在 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 的一部分。

如果有人能给我一些建议,我将不胜感激。

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案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>
    

    【讨论】:

      【解决方案2】:

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

      客户表格视图

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

      【讨论】:

      • 谢谢,但这如何适用于我询问 Intent 和 HasUnevenRows 的问题。如果可能的话,您能否提供完整的答案,以便我和其他人可以看到需要什么。
      • 我试过了,但似乎因为我从 TableView 继承,所以不需要向 ExtFooterTableView 添加属性,因为它已经有了它们。我已经稍微更新了这个问题,因为我注意到问题不在于没有设置高度,但似乎 ViewCell 和 TextCell 的处理方式有所不同。也许你可以复制这个。谢谢
      • 好的,我已经删除了这个属性,你之前问错问题了。
      • 是的,在我尝试了您的解决方案后,我意识到它是继承的并且不需要。仍然想知道行高发生了什么,所以留下了问题,只是改变了标题,因为它仍然是一个问题。谢谢
      猜你喜欢
      • 2018-06-12
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      • 2012-09-13
      • 2020-10-28
      • 1970-01-01
      相关资源
      最近更新 更多