Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 58056

Custom Header On TableView (not Section Group Header)

$
0
0

Hello,

I am trying to create a TableView custom renderer for iOS and Android that will allow me to bind a custom view and apply it as a static header in either an Android ListView or an iOS UITableView. I currently have the following classes configured:

// main view   
public class ExtendedTableView : TableView
{
    public static readonly BindableProperty HeaderProperty = BindableProperty.Create<ExtendedTableView, View>(
            p => p.Header, null);

    public View Header
    {
        get { return (View)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }
}

<!-- XAML -->
<controls:ExtendedTableView
    Intent="Settings"
    BackgroundColor="{x:Static res:Colors.COLOR_APP_LIGHT_BLUE}">
    <controls:ExtendedTableView.Header>
        <Label Text="Hello World" />
    </controls:ExtendedTableView.Header>
    <TableView.Root>
        <TableRoot> 
            <TableSection>
                    <TextCell
                        x:Name="ContactUsCell"
                        Text="Contact Us" />
                </TableSection>           
        </TableRoot>
    </TableView.Root>
</controls:ExtendedTableView>

// ios TableViewRenderer
public class ExtendedTableViewRenderer : TableViewRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TableView> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {
            var listView = (ExtendedTableView)e.NewElement;
            var _tableView = this.Control;

            var headerView = RendererFactory.GetRenderer(listView.Header);

            _tableView.TableHeaderView = headerView.NativeView;
        }
    }
}

// droid TableViewRenderer
public class ExtendedTableViewRenderer : TableViewRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TableView> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {
            var extedned = (ExtendedTableView)e.NewElement;
            var listView = this.Control;

            if (extedned.Header != null)
            {
                var view = RendererFactory.GetRenderer(extedned.Header);

                var group = view.ViewGroup;

                listView.AddHeaderView(group);
            }
        }
    }
}

The problem I'm having is that the width/height is not defined for the view at the the time that it is added to the native control in the native renderer. It works on iOS if I create a view manually and set a frame in the renderer (still haven't gotten it to work on android). I know that the height & width values are not created directly when calling RenderFactory.GetRenderer(). From my understanding there is a process in the framework that determines the height/width once it is a added to the parent view. I just don't know how to trigger the creation of the frame.

Is there a way to get something like this to work?

I don't want to use 2 separate views in my page. I need my header to scroll with the list/table rather than behind it, so I thought this would be a valid approach to try. If this is not possible -- first it would be a stellar feature to have -- second, is there a way to do something similar? I would like to have a reusable control that I can use throughout my app where I can define a TableView or a ListView and add a static header to the layout that will scroll with the list/table. Since a UITableView or ListView scrolls independently, I'm not sure how it would work to wrap everything in a scroll view.

I am open to suggestions in any facet. I'd like to get this custom control to work if its possible, otherwise an alternative approach would work too.


Viewing all articles
Browse latest Browse all 58056

Trending Articles