Search code examples
listviewxamarin.formsmultiple-columns

Xamarin.Forms multi column table GUI


Is ListView the right option to create a table? Something like this?

Enter image description here

The cell content is text only, but I need to be able to show something like a drop down menu on cell touch with the few most common options and text field for custom entry.

There will be a maximum of 80 to 100 lines of data, usually much less.


Solution

  • ListView is indeed the best way to approximate a table. Here is an example...

    <ListView x:Name="listViewm" ItemsSource="{Binding MyItems}">
        <ListView.Header>
            <Grid BackgroundColor="Black">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*" />
                    <ColumnDefinition Width="1*" />
                    <ColumnDefinition Width="1*" />
                    <ColumnDefinition Width="1*" />
                </Grid.ColumnDefinitions>
                <Label Text="Switch" HorizontalOptions="Fill"  Grid.Column="0" FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="1"/>
                <Label Text="Addend 1" HorizontalOptions="Fill" Grid.Column="1" FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="1"/>
                <Label Text="Addend 2" HorizontalOptions="Fill" Grid.Column="2" FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="1"/>
                <Label Text="Result" HorizontalOptions="Fill" Grid.Column="3" FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="1"/>
            </Grid>
        </ListView.Header>
    
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid BackgroundColor="Black">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="1*" />
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Text ="{Binding Switch}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="1"></Label>
                        <Label Grid.Column="1" Text ="{Binding Addend1}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="1"></Label>
                        <Label Grid.Column="2" Text ="{Binding Addend2}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="1"></Label>
                        <Label Grid.Column="3" Text ="{Binding Result}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="1"></Label>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    This is the code in the view model...

    public class MyItem : INotifyPropertyChanged
    {
        bool _switch = false;
    
        public bool Switch
        {
            get
            {
                return _switch;
            }
    
            set
            {
                if (_switch != value)
                {
                    _switch = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Switch"));
                }
            }
    
        }
    
        public int Addend1 { get; set; }
    
        public int Addend2 { get; set; }
    
        public int Result
        {
            get
            {
                return Addend1 + Addend2;
            }
        }
    
        public string Summary
        {
            get
            {
                return Addend1 + " + " + Addend2 + " = " + Result;
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    
    //...
    
    public MyItems ObservableCollection<MyItem> { get; set; }
    
    //...
    
    MyItems = new ObservableCollection<MyItem>();
    MyItems.Add(new MyItem() { Switch = true, Addend1 = 1, Addend2 = 2 });
    MyItems.Add(new MyItem() { Switch = false, Addend1 = 1, Addend2 = 2 });
    MyItems.Add(new MyItem() { Switch = true, Addend1 = 2, Addend2 = 3 });
    MyItems.Add(new MyItem() { Switch = false, Addend1 = 2, Addend2 = 3 });
    

    This results in a table that looks like this...

    ListView as table

    I am not sure why the gutters between columns are so wide.

    You can define menu items on ViewCell.ContextActions.