Forum Xamarin.Forms

TableSection w/out header

MikeMuegelMikeMuegel USMember
edited June 2014 in Xamarin.Forms

How can I hide / not create the section header created by a TableSection? The TableSectionBase documentation states:

You can assign a header and a footer either as strings (Header and Footer) properties, or as Views to be shown (HeaderView and FooterView). Internally this uses the same storage, so you can only show one or the other.

But I could not find HeaderView property to create zero height section.

«1

Posts

  • MitchMilamMitchMilam USMember ✭✭✭

    Mike, I think this is a case of the documentation being incorrect or ahead of the actual implementation.

    For instance: I can't find any classes called HeaderView or FooterView, so I would assume that is part of the future roadmap.

    Mitch

  • MarshallMarshall USMember ✭✭

    if you are wanting to display a list without a header, I would suggest using a ListView instead

  • MichaelMuegelMichaelMuegel US ✭✭
    edited June 2014

    @Marshall I want first section to have no header, others to have one. I can certainly roll my own via stack, but Android and iOS at least support section view tweaking and I want to stick w/ tableview.

  • CraigDunnCraigDunn USXamarin Team Xamurai
    edited June 2014

    If you're using a TableView, check out this sample: DialogPro. It contains a simple, multi-section TableView.

    A TableSection() without a title specified will not render the header; a TableSection("Ring") with the title specified will render a header row/separator.

    Note that I purposefully use TableSection(" "), passing an empty string to force a blank header row.

  • gattacagattaca USMember

    Xaml will show the header, even TableSection title is set to a blank space string.
    (Xamarin.Forms.1.2.1.6229)

    <TableView Intent="Menu" BackgroundColor="Silver">
        <TableView.Root>
            <TableRoot>
                <TableSection Title=" ">
                    <TextCell Text ="Email" TextColor = "Red"/>
                    <TextCell Text ="Password"/>
                    <TextCell Text ="RePassword"/>
                </TableSection>              
            </TableRoot>
        </TableView.Root>
    </TableView>
    
  • CraigDunnCraigDunn USXamarin Team Xamurai

    Thanks @gattaca‌ you're right - the behavior differs between C# and Xaml... will have to investigate further.

  • gattacagattaca USMember

    The bug is still exist at Xamarin.Forms.1.2.2.6243

  • TomYuTomYu USMember
    edited September 2014

    I'm unable to remove the TableSection Header for Android.

  • chris_riesgochris_riesgo USUniversity ✭✭✭
    edited September 2014

    @CraigDunn‌ - The following still generates a TableView header row & separator with some height on Android. Ultimately, it adds a cell's height of empty space above the TableView:

    var section = new TableSection(" ");
    // also tried -- does the same
    // var section = new TableSection("");
    section.Add(cells);
    var root = new TableRoot();
    root.Add(section);
    tableView.Root = root;
    

    Upon inspecting the generated TableView from an attached TableViewRenderer, it looks like it's just adding +1 row for each section header. Looks like I'll need to somehow tag the section header rows and manually remove them in the renderer

  • CraigDunnCraigDunn USXamarin Team Xamurai

    @chris_riesgo‌ ugh, have you seen a bug already raised for this? I think there is... but I know this stuff has been worked on so maybe the behavior has 'changed' but still isn't 'right'...

  • chris_riesgochris_riesgo USUniversity ✭✭✭

    @CraigDunn‌ - I'll do some digging on bugzilla, and log a bug with repro if one doesn't already exist.

  • chris_riesgochris_riesgo USUniversity ✭✭✭

    @CraigDunn‌ - the issue has already been marked as Confirmed in bugzilla: https://bugzilla.xamarin.com/show_bug.cgi?id=21446

    As a side note, I see the issue in the 1.2.3 pre-1 XF release as well.

  • chris_riesgochris_riesgo USUniversity ✭✭✭
    edited September 2014

    @JoeManke‌ - What does your ExportRenderer statement look like? (i.e. - what are you mapping the renderer to?)

    [assembly: ExportRenderer(typeof(**?**), typeof(TableSectionHeaderRenderer))]

  • JoeMankeJoeManke USMember ✭✭✭✭✭

    @chris_riesgo‌ Sorry, forgot that bit. Rendering the default TextCell.

    [assembly: ExportRenderer(typeof(TextCell), typeof(TableSectionHeaderRenderer))]

  • D-BotD-Bot CAUniversity ✭✭

    I was able to get a TableView with a zero height section header with this code. Using TableIntent.Data removed it for me.

        var tableView = new TableView {
                Intent = TableIntent.Data,
                HasUnevenRows = true,
                Root = new TableRoot () 
                { 
                    new TableSection () 
                    { 
                        customCell
                    }
                }
            };
    
  • DemiVisionDemiVision USMember ✭✭

    That worked for you on Android? Doesn't seem to work for me (at least on latest Beta channel version). Also for me, the custom renderer option does not work. GetCellCore only gets called for the "real" rows, not for the section headers. What am I doing wrong?

  • StefanMobileStefanMobile NLUniversity ✭✭
    edited December 2014

    I tried the custom renderer which JoeManke posted. This works fine until I change the row height of the tableview like:
    tableView.RowHeight = 70;

    Any solution for that?

  • IssamMeIssamMe USMember
    edited December 2014

    On Android, the custom renderer option works if HasUnevenRows isn't set to true ...

    And on iOS : tableView.Intent = TableIntent.Data; works fine

  • voidvoid DKBeta ✭✭✭

    I'm having this problem on Droid (API 19) with 1.3.0 pre2. Perhaps it is time to fix this?

  • KzettlKzettl USMember

    I currently am having the same issue with the TableSection Header leaving an empty space in WinPhone. I used @JoeManke‌'s solution for Android, and on iOS I didn't have an issue. But I still have the issue on WinPhone. I tried to create some type of Renderer which would get rid of the cell, but I haven't had any luck with a solution. Has anyone else had this problem and find a solution to it?

  • RodyLagerwaardRodyLagerwaard USMember ✭✭

    Dit someone found a solution for Windows Phone?

  • voidvoid DKBeta ✭✭✭
    edited January 2015

    I wonder if a scrollview with buttons/labels/etc would'nt be the best route. TableViews seems like abandonware

  • IanVinkIanVink CAInsider, University ✭✭✭

    This code works for me. Just make sure that the Section has no text. It'll remove all sections from all tables that have no text.

    [assembly: ExportRenderer(typeof(TextCell), typeof(AAATextCellRenderer))]
    
    namespace AAA.Android.Renderers
    {
    
        /// <summary>
        /// Will force Android TableViews with a blank Seaction to not render. Otherwise it will render a blank line
        /// </summary>
        public class AAATextCellRenderer : Xamarin.Forms.Platform.Android.TextCellRenderer
        {
            protected override global::Android.Views.View GetCellCore(Cell item, global::Android.Views.View convertView, ViewGroup parent, Context context)
            {
                var view = base.GetCellCore(item, convertView, parent, context) as ViewGroup;
    
                if (item is TextCell)
                    if (String.IsNullOrEmpty((item as TextCell).Text))
                    {
                        if (view != null)
                        {
                            view.Visibility = ViewStates.Gone;
                            while (view.ChildCount > 0)
                                view.RemoveViewAt(0);
                            view.SetMinimumHeight(0);
                            view.SetPadding(0, 0, 0, 0);
                        }
                    }
    
                return view;
            }
        }
    }
    
  • GeniusInPyjamasGeniusInPyjamas USMember ✭✭

    @IanVink
    This solved my problem but there is a blue line on the menu beginning, it's possible to be removed?

  • rudyrykrudyryk RUMember ✭✭✭
    edited April 2015

    @IanVink Thank you, that's working great! And +1 to @GeniusInPyjamas, there's still a blue line out of nowhere at the top of table view, e.g. at the bottom of first null-height header :)

    Does anybody know how to remove it or change its color?

  • Daniel.5649Daniel.5649 USMember

    Has anyone worked out to do this on WP8? It adds a large header to the view and doesn't look right on the eye at all.

    Thanks

    Dan

  • jzeferinojzeferino USUniversity ✭✭

    Guys i found a solution/workaround to solve the blue line in android here: https://forums.xamarin.com/discussion/comment/132243/#Comment_132243

  • DavidColvin.0220DavidColvin.0220 USMember, University

    I think it has to do with the intent property. Set it to Data and the headers disappear.

  • AdamHewittAdamHewitt USMember
    edited December 2015

    The most workable solutions thus far modify the TextCell, hiding it regardless of whether it is a header or item, and without checking the Detail property to perhaps still show the item. This seemed too heavy-handed to me, so I have done the following.

    This isn't for the faint of heart, as it does use Reflection to access a private base member. I've justified this given:

    1. It's a narrow situation.
    2. Breaking changes in Forms will immediately fail in testing.
    3. The private member is an overload of a public one, so I don't even need a magic string with C#6 nameof(GetCellForPosition).
    using Android.Content;
    using Android.Views;
    using BiblePlus.Droid.Views.Controls;
    using System.Linq;
    using System.Reflection;
    using Xamarin.Forms;
    using ListView = Android.Widget.ListView;
    using View = Android.Views.View;
    
    [assembly: ExportRenderer(typeof(TableView), typeof(MyTableViewRenderer))]
    
    namespace BiblePlus.Droid.Views.Controls
    {
        class MyTableViewRenderer : Xamarin.Forms.Platform.Android.TableViewRenderer
        {
            protected override Xamarin.Forms.Platform.Android.TableViewModelRenderer GetModelRenderer(ListView listView, TableView view)
            {
                return new MyTableViewModelRenderer(Context, listView, view);
            }
    
    
            class MyTableViewModelRenderer : Xamarin.Forms.Platform.Android.TableViewModelRenderer
            {
                //Info on private base class method
                private static readonly MethodInfo CellForPosition = typeof(Xamarin.Forms.Platform.Android.TableViewModelRenderer)
                    .GetMethod(nameof(GetCellForPosition), BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any,
                        new[] { typeof(int), typeof(bool).MakeByRefType(), typeof(bool).MakeByRefType() }, null);
    
    
                private readonly TableView _view;
    
                public MyTableViewModelRenderer(Context context, ListView listView, TableView view)
                    : base(context, listView, view)
                {
                    _view = view;
                }
    
                public override View GetView(int position, View convertView, ViewGroup parent)
                {
                    var cellView = base.GetView(position, convertView, parent);
    
                    if (_view.Intent == TableIntent.Data)
                    {
                        var @params = new object[] { position, false, false };
                        var cell = CellForPosition.Invoke(this, @params) as Cell;   //Reflection to base method to determine cell type
    
                        bool shouldHide = (bool) @params[1] /*out isHeader*/
                                          && string.IsNullOrEmpty((cell as TextCell)?.Text);
    
                        //With view recycling, we need to ensure Visibility is set to the proper value
                        var visibility = shouldHide
                            ? ViewStates.Gone
                            : ViewStates.Visible;
    
                        cellView.Visibility = visibility;
    
                        var cellGroup = cellView as ViewGroup;
                        if (cellGroup != null)
                        {
                            foreach (var child in Enumerable.Range(0, cellGroup.ChildCount).Select(cellGroup.GetChildAt))
                                child.Visibility = visibility;
                        }
                    }
    
                    return cellView;
                }
            }
        }
    }
    
  • JoaoCoutinhoJoaoCoutinho USMember

    Has anyone found an alternative/final solution for Windows Phone?

  • chualichuali USMember

    finally I found a solution

    class BaseTableViewModelRenderer : TableViewModelRenderer
    {
    public BaseTableViewModelRenderer(Context context, Android.Widget.ListView listView, TableView view)
    : base(context, listView, view)
    {
    }
    public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
    {
    var view = base.GetView(position, convertView, parent);

            if (GetCellForPosition(position).GetType() != typeof(TextCell)) return view;
            //no headersection
            //return new Android.Views.View(Context);
           //has headersection
            view.LayoutParameters.Height = 10;
            return view;
        }
    }
    
  • HelloWorldThereHelloWorldThere USMember ✭✭

    The Xaml bug still exist..

  • RyanFrenchRyanFrench USMember ✭✭

    Any word on when this bug will be fixed?

  • HeshanPathiranaHeshanPathirana LKMember ✭✭

    The Xaml bug stil exist! :worried:

  • ZaneCampbellZaneCampbell USMember ✭✭

    Thank you! That worked for hiding the header.

    @DavidColvin.0220 said:
    I think it has to do with the intent property. Set it to Data and the headers disappear.

  • SergeyPolezhaevSergeyPolezhaev RUMember ✭✭

    Seems like it is fixed in latest Xamarin Forms 2.3.4 package

  • AlexBrownAlexBrown USMember ✭✭

    The BUG was gone... is it back now...? Suddenly it is not working in XAML again after getting latest Xamarin packages.

  • AlexRutherfordAlexRutherford GBUniversity ✭✭
    edited November 2017

    I just ran into this problem for iOS. I have created a custom renderer with the following.

    var nc = (UITableView)Control;
    if (nc != null)
    {
        // No headers for us!
        nc.EstimatedSectionHeaderHeight = 0;
    }
    

    This solves the problem for me.

Sign In or Register to comment.