Skip to content

Commit

Permalink
Merge pull request #121 from symbiogenesis/sensible-layout
Browse files Browse the repository at this point in the history
Make the layout sensible
  • Loading branch information
symbiogenesis authored Jan 23, 2024
2 parents 20a0308 + af6cc33 commit 0853f2e
Show file tree
Hide file tree
Showing 11 changed files with 553 additions and 439 deletions.
11 changes: 7 additions & 4 deletions Maui.DataGrid.Sample/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
<Button Text="Settings" WidthRequest="100" Clicked="OnSettingsClicked" />
</Grid>

<dg:DataGrid Grid.Row="1" ItemsSource="{Binding Teams}" SelectionMode="{Binding SelectionMode}" SelectedItem="{Binding SelectedTeam}"
RowHeight="70" HeaderHeight="50" BorderColor="{StaticResource GridBorderColor}" RowToEdit="{Binding TeamToEdit}"
<dg:DataGrid Grid.Row="1" ItemsSource="{Binding Teams}" SelectionMode="{Binding SelectionMode}"
SelectedItem="{Binding SelectedTeam}" RowToEdit="{Binding TeamToEdit}"
BorderColor="{StaticResource GridBorderColor}" BorderThickness="{Binding BorderThickness}"
HeaderBackground="{StaticResource GridHeaderBgColor}" HeaderBordersVisible="{Binding HeaderBordersVisible}"
PullToRefreshCommand="{Binding Commands[Refresh]}" IsRefreshing="{Binding IsRefreshing}"
BackgroundColor="{StaticResource GridBgColor}" ActiveRowColor="{StaticResource ActiveRowColor}"
FooterBackground="{StaticResource GridFooterBgColor}"
PaginationEnabled="{Binding PaginationEnabled}" PageSize="{Binding PageSize}"
ActiveRowColor="{StaticResource ActiveRowColor}" FooterBackground="{StaticResource GridFooterBgColor}" x:Name="_dataGrid1">
PullToRefreshCommand="{Binding Commands[Refresh]}" IsRefreshing="{Binding IsRefreshing}"
RowHeight="70" HeaderHeight="50" x:Name="_dataGrid1">
<dg:DataGrid.Columns>
<dg:DataGridColumn Title="Logo" PropertyName="Logo" SortingEnabled="False">
<dg:DataGridColumn.CellTemplate>
Expand Down
1 change: 1 addition & 0 deletions Maui.DataGrid.Sample/Resources/Styles/Colors.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@
<Color x:Key="GridHeaderBgColor">#E0E6F8</Color>
<Color x:Key="GridFooterBgColor">#E0E6F8</Color>
<Color x:Key="GridBorderColor">#CCCCCC</Color>
<Color x:Key="GridBgColor">#CCCCCC</Color>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions Maui.DataGrid.Sample/SettingsPopup.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
<CheckBox IsChecked="{Binding HeaderBordersVisible}" />
<Label Text="Header Borders Visible?" TextColor="White" VerticalOptions="Center" />
</HorizontalStackLayout>
<HorizontalStackLayout Style="{StaticResource SampleContainerStyle}">
<Stepper Minimum="0" Maximum="10" Value="{Binding BorderThicknessNumeric}"
BackgroundColor="{OnPlatform WinUI=Gray}"/>
<Label Text="Border Thickness" TextColor="White" VerticalOptions="Center" />
</HorizontalStackLayout>
<HorizontalStackLayout Style="{StaticResource SampleContainerStyle}">
<CheckBox IsChecked="{Binding WonColumnVisible}" />
<Label Text="Won Column" TextColor="White" VerticalOptions="Center" />
Expand Down
15 changes: 15 additions & 0 deletions Maui.DataGrid.Sample/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public MainViewModel()
TeamColumnWidth = 70;
SelectionMode = SelectionMode.Single;
PageSize = 6;
BorderThicknessNumeric = 1;

Commands.Add("CompleteEdit", new Command(CmdCompleteEdit));
Commands.Add("Edit", new Command<Team>(CmdEdit));
Expand Down Expand Up @@ -60,6 +61,20 @@ public bool WonColumnVisible
set => SetValue(value);
}

public double BorderThicknessNumeric
{
get => GetValue<double>();
set
{
if (SetValue(value))
{
OnPropertyChanged(nameof(BorderThickness));
}
}
}

public Thickness BorderThickness => new(BorderThicknessNumeric);

public ushort TeamColumnWidth
{
get => GetValue<ushort>();
Expand Down
6 changes: 4 additions & 2 deletions Maui.DataGrid.Sample/ViewModels/ViewModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ protected ViewModelBase()
Commands = [];
}

protected void SetValue(object value, [CallerMemberName] string propertyName = null)
protected bool SetValue(object value, [CallerMemberName] string propertyName = null)
{
if (_properties.TryGetValue(propertyName!, out var item) && item == value)
{
return;
return false;
}

_properties[propertyName!] = value;
OnPropertyChanged(propertyName);

return true;
}

protected T GetValue<T>([CallerMemberName] string propertyName = null)
Expand Down
2 changes: 1 addition & 1 deletion Maui.DataGrid/DataGrid.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<CollectionView
x:Name="_collectionView"
WidthRequest="{Binding WidthRequest, Source={Reference self}}"
BackgroundColor="{Binding BorderColor, Source={Reference self}}"
BackgroundColor="{Binding BackgroundColor, Source={Reference self}}"
SelectedItem="{Binding SelectedItem, Source={Reference self}, Mode=TwoWay}"
SelectedItems="{Binding SelectedItems, Source={Reference self}, Mode=TwoWay}"
ItemSizingStrategy="{Binding ItemSizingStrategy, Source={Reference self}}"
Expand Down
108 changes: 62 additions & 46 deletions Maui.DataGrid/DataGrid.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,9 @@ private void SortAndPaginate(SortData? sortData = null)
var self = (DataGrid)b;
if (o != n && self._headerView != null && !self.HeaderBordersVisible)
{
foreach (var child in self._headerView.Children.OfType<View>())
foreach (var cell in self._headerView.Children.OfType<DataGridCell>())
{
child.BackgroundColor = n;
cell.UpdateCellColors(n);
}
}
});
Expand All @@ -306,18 +306,16 @@ private void SortAndPaginate(SortData? sortData = null)
/// </summary>
public static readonly BindableProperty BorderColorProperty =
BindablePropertyExtensions.Create<DataGrid, Color>(Colors.Black,
propertyChanged: (b, _, n) =>
propertyChanged: (b, _, _) =>
{
var self = (DataGrid)b;

if (self._headerView != null && self.HeaderBordersVisible)
{
self._headerView.BackgroundColor = n;
self.InitHeaderView();
}

if (self.Columns != null && self.ItemsSource != null)
{
self.Reload();
}
self.Reload();
});

/// <summary>
Expand Down Expand Up @@ -684,22 +682,20 @@ private void SortAndPaginate(SortData? sortData = null)
/// Gets or sets the thickness of the border around the DataGrid.
/// </summary>
public static readonly BindableProperty BorderThicknessProperty =
BindablePropertyExtensions.Create<DataGrid, Thickness>(new Thickness(1),
propertyChanged: (b, o, n) =>
{
if (o != n && b is DataGrid self && self.IsLoaded)
{
self.Reload();
}
});
BindablePropertyExtensions.Create<DataGrid, Thickness>(new Thickness(1), BindingMode.TwoWay);

/// <summary>
/// Gets or sets a value indicating whether the header borders are visible in the DataGrid.
/// </summary>
public static readonly BindableProperty HeaderBordersVisibleProperty =
BindablePropertyExtensions.Create<DataGrid, bool>(true,
propertyChanged: (b, _, n) => ((DataGrid)b)._headerView.BackgroundColor =
n ? ((DataGrid)b).BorderColor : ((DataGrid)b).HeaderBackground);
propertyChanged: (b, _, _) =>
{
if (b is DataGrid self)
{
self.InitHeaderView();
}
});

/// <summary>
/// Gets or sets the index of the sorted column in the DataGrid.
Expand Down Expand Up @@ -1079,7 +1075,7 @@ public bool RefreshingEnabled
}

/// <summary>
/// Border thickness for header &amp; each cell
/// Border thickness for cells
/// </summary>
public Thickness BorderThickness
{
Expand Down Expand Up @@ -1348,30 +1344,32 @@ internal void Reload()

#region Header Creation Methods

private View GetHeaderViewForColumn(DataGridColumn column)
private DataGridCell CreateHeaderCell(DataGridColumn column)
{
View cellContent;

column.HeaderLabel.Style = column.HeaderLabelStyle ?? HeaderLabelStyle ?? _defaultHeaderStyle;

if (!IsSortable || !column.SortingEnabled || !column.IsSortable())
{
return new ContentView
cellContent = new ContentView
{
Content = column.HeaderLabel
};
}

var sortIconSize = HeaderHeight * 0.3;
column.SortingIconContainer.HeightRequest = sortIconSize;
column.SortingIconContainer.WidthRequest = sortIconSize;
column.SortingIcon.Style = SortIconStyle ?? _defaultSortIconStyle;

var grid = new Grid
else
{
ColumnSpacing = 0,
Padding = new(0, 0, 4, 0),
ColumnDefinitions = HeaderColumnDefinitions,
Children = { column.HeaderLabel, column.SortingIconContainer },
GestureRecognizers =
var sortIconSize = HeaderHeight * 0.3;
column.SortingIconContainer.HeightRequest = sortIconSize;
column.SortingIconContainer.WidthRequest = sortIconSize;
column.SortingIcon.Style = SortIconStyle ?? _defaultSortIconStyle;

cellContent = new Grid
{
Padding = new(0, 0, 4, 0),
ColumnDefinitions = HeaderColumnDefinitions,
Children = { column.HeaderLabel, column.SortingIconContainer },
GestureRecognizers =
{
new TapGestureRecognizer
{
Expand All @@ -1391,22 +1389,24 @@ private View GetHeaderViewForColumn(DataGridColumn column)
CommandParameter = column
}
}
};
};

Grid.SetColumn(column.SortingIconContainer, 1);
}

Grid.SetColumn(column.SortingIconContainer, 1);
return grid;
return new DataGridCell(cellContent, HeaderBackground, column, false);
}

private void InitHeaderView()
{
SetColumnsBindingContext();

_headerView.Children.Clear();
if (_headerView == null)
{
return;
}

_headerView.Padding = new(BorderThickness.Left, BorderThickness.Top, BorderThickness.Right, 0);
_headerView.ColumnSpacing = BorderThickness.HorizontalThickness;
SetColumnsBindingContext();

if (Columns == null || Columns.Count == 0)
if (Columns == null)
{
_headerView.ColumnDefinitions.Clear();
return;
Expand Down Expand Up @@ -1437,12 +1437,28 @@ private void InitHeaderView()
continue;
}

col.HeaderView ??= GetHeaderViewForColumn(col);
col.HeaderCell ??= CreateHeaderCell(col);

col.HeaderView.SetBinding(BackgroundColorProperty, new Binding(nameof(HeaderBackground), source: this));
col.HeaderCell.UpdateBindings(this, HeaderBordersVisible);

if (_headerView.Children.TryGetItem(i, out var existingCell))
{
if (existingCell is not DataGridCell cell)
{
throw new InvalidDataException($"{nameof(DataGridRow)} should only contain {nameof(DataGridCell)}s");
}

if (cell.Column != col)
{
Grid.SetColumn(col.HeaderCell, i);
}
}
else
{
Grid.SetColumn(col.HeaderCell, i);
_headerView.Children.Add(col.HeaderCell);
}

Grid.SetColumn(col.HeaderView, i);
_headerView.Children.Add(col.HeaderView);
}

// Remove extra columns
Expand Down
66 changes: 66 additions & 0 deletions Maui.DataGrid/DataGridCell.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
namespace Maui.DataGrid;

using Microsoft.Maui.Controls;

/// <summary>
/// Specifies each cell of the DataGrid.
/// </summary>
internal sealed class DataGridCell : Grid
{
internal DataGridCell(View cellContent, Color? backgroundColor, DataGridColumn column, bool isEditing)

{
var colorfulCellContent = new ContentView
{
BackgroundColor = backgroundColor,
Content = cellContent,
};

Content = cellContent;
Column = column;
IsEditing = isEditing;

Children.Add(colorfulCellContent);
}

public View Content { get; }

public DataGridColumn Column { get; }
public bool IsEditing { get; }


internal void UpdateBindings(DataGrid dataGrid, bool bordersVisible = true)
{
// The DataGridCell is a grid, and the padding constitutes the cell's border
// And the Background constitutes the border color of the cell.

if (bordersVisible)
{
BackgroundColor = dataGrid.BorderColor;
Padding = dataGrid.BorderThickness;

SetBinding(BackgroundColorProperty, new Binding(nameof(DataGrid.BorderColor), source: dataGrid));
SetBinding(PaddingProperty, new Binding(nameof(DataGrid.BorderThickness), source: dataGrid));
}
else
{
Padding = 0;

RemoveBinding(BackgroundColorProperty);
RemoveBinding(PaddingProperty);
}
}

internal void UpdateCellColors(Color? bgColor, Color? textColor = null)
{
foreach (var cellContent in Children.OfType<ContentView>())
{
cellContent.BackgroundColor = bgColor;

if (cellContent.Content is Label label && textColor != null)
{
label.TextColor = textColor;
}
}
}
}
2 changes: 1 addition & 1 deletion Maui.DataGrid/DataGridColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ internal ColumnDefinition? ColumnDefinition
set => _columnDefinition = value;
}

internal View? HeaderView { get; set; }
internal DataGridCell? HeaderCell { get; set; }

internal TextAlignment VerticalTextAlignment => _verticalTextAlignment ??= VerticalContentAlignment.ToTextAlignment();

Expand Down
Loading

0 comments on commit 0853f2e

Please sign in to comment.