Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageVersion Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.Controls.TreeDataGrid" Version="11.1.0" />
<PackageVersion Include="Avalonia.Controls.ItemsRepeater" Version="11.0.9" />
<PackageVersion Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.Themes.Simple" Version="$(AvaloniaVersion)" />
Expand All @@ -33,4 +34,4 @@
<!--For _build-->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<!--Since Material.Avalonia.DataGrid included as a ProjectReference, auto-imports doesn't work properly-->
<ItemGroup>
<RuntimeHostConfigurationOption Include="MaterialThemeIncludeDataGrid" Value="true"/>
<RuntimeHostConfigurationOption Include="MaterialThemeIncludeTreeDataGrid" Value="true"/>
<TrimmerRootAssembly Include="Material.Avalonia.DataGrid"/>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<!--Since Material.Avalonia.DataGrid included as a ProjectReference, auto-imports doesn't work properly-->
<ItemGroup>
<RuntimeHostConfigurationOption Include="MaterialThemeIncludeDataGrid" Value="true"/>
<RuntimeHostConfigurationOption Include="MaterialThemeIncludeTreeDataGrid" Value="true"/>
<TrimmerRootAssembly Include="Material.Avalonia.DataGrid"/>
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions Material.Avalonia.Demo/Material.Avalonia.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<PackageReference Include="ShowMeTheXaml.Avalonia.Generator" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Material.Avalonia.TreeDataGrid\Material.Avalonia.TreeDataGrid.csproj" />
<ProjectReference Include="..\Material.Avalonia\Material.Avalonia.csproj" />
<ProjectReference Include="..\Material.Avalonia.Dialogs\Material.Avalonia.Dialogs.csproj" />
<ProjectReference Include="..\Material.Avalonia.DataGrid\Material.Avalonia.DataGrid.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Media;

namespace Material.Avalonia.TreeDataGrid.Converters;

public sealed class TreeDataGridSourceColumnAlignmentToDockConverter : IMultiValueConverter
{
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
if (values[0] is not ITreeDataGridSource source ||
values[1] is not int columnIndex ||
columnIndex < 0 ||
columnIndex >= source.Columns.Count)
return Dock.Left;

var column = source.Columns[columnIndex];
var align = TextColumnAlignmentProvider.GetTextAlignment(column);

return align == TextAlignment.Right ? Dock.Right : Dock.Left;
}

public object[] ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture)
=> throw new NotSupportedException();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>TreeDataGrid styles library of Material.Avalonia.</Description>
<PackageTags>avalonia xaml material design theme treedatagrid colour color ui ux material-design google-material</PackageTags>
<PackageIcon>FavIcon.png</PackageIcon>

<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<None Include="../wiki/FavIcon.png" Pack="true" PackagePath="/" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Avalonia.Controls.TreeDataGrid" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Material.Avalonia\Material.Avalonia.csproj"/>
</ItemGroup>

<ItemGroup>
<Content Include="*.props">
<Pack>true</Pack>
<PackagePath>build\;buildTransitive\</PackagePath>
</Content>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<RuntimeHostConfigurationOption Include="MaterialThemeIncludeTreeDataGrid" Value="true"/>
<!--To exclude this library from trimming-->
<TrimmerRootAssembly Include="Material.Avalonia.TreeDataGrid" RootMode="library"/>
</ItemGroup>
</Project>
18 changes: 18 additions & 0 deletions Material.Avalonia.TreeDataGrid/MaterialTreeDataGridStyles.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<treeDataGrid:MaterialTreeDataGridStyles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:treeDataGrid="clr-namespace:Material.Avalonia.TreeDataGrid"
x:Class="Material.Avalonia.TreeDataGrid.MaterialTreeDataGridStyles">
<treeDataGrid:MaterialTreeDataGridStyles.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGridCheckBoxCell.axaml" />
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGridExpanderCell.axaml" />
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGridTemplateCell.axaml" />
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGridTextCell.axaml" />
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGridRow.axaml" />
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGridColumnHeader.axaml" />
<ResourceInclude Source="avares://Material.Avalonia.TreeDataGrid/TreeDataGrid.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</treeDataGrid:MaterialTreeDataGridStyles.Resources>
</treeDataGrid:MaterialTreeDataGridStyles>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Material.Avalonia.TreeDataGrid;

public class MaterialTreeDataGridStyles : global::Avalonia.Styling.Styles {
}
40 changes: 40 additions & 0 deletions Material.Avalonia.TreeDataGrid/TextColumnAlignmentProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Media;

namespace Material.Avalonia.TreeDataGrid;

internal static class TextColumnAlignmentProvider
{
private static readonly ConcurrentDictionary<Type, Func<object, TextAlignment?>> _cache = new();

public static TextAlignment? GetTextAlignment(object column)
{
ArgumentNullException.ThrowIfNull(column);

var colType = column.GetType();
if (!colType.IsGenericType
|| colType.GetGenericTypeDefinition() != typeof(TextColumn<,>))
return null;

var getter = _cache.GetOrAdd(colType, BuildGetter);
return getter(column);
}

[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
private static Func<object, TextAlignment?> BuildGetter(Type closedColumnType)
{
var helperMethod = typeof(TextColumnHelper)
.GetMethod(nameof(TextColumnHelper.GetTextAlignmentGeneric),
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)!;

var genArgs = closedColumnType.GetGenericArguments();
var closedMethod = helperMethod.MakeGenericMethod(genArgs);

return (Func<object, TextAlignment?>)closedMethod
.CreateDelegate(typeof(Func<object, TextAlignment?>));
}
}
14 changes: 14 additions & 0 deletions Material.Avalonia.TreeDataGrid/TextColumnHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Media;

namespace Material.Avalonia.TreeDataGrid;

internal static class TextColumnHelper
{
public static TextAlignment? GetTextAlignmentGeneric<TModel, TValue>(object column)
where TModel : class
{
var typed = (TextColumn<TModel, TValue>)column;
return typed.Options.TextAlignment;
}
}
63 changes: 63 additions & 0 deletions Material.Avalonia.TreeDataGrid/TreeDataGrid.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type TreeDataGrid}" TargetType="TreeDataGrid">
<Setter Property="CornerRadius" Value="4" />
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDividerBrush}" />
<Setter Property="Template">
<ControlTemplate>
<Border x:Name="RootBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<DockPanel>
<ScrollViewer x:Name="PART_HeaderScrollViewer"
DockPanel.Dock="Top"
IsVisible="{TemplateBinding ShowColumnHeaders}"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Disabled"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}">
<Border x:Name="ColumnHeadersPresenterBorder">
<TreeDataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"
ElementFactory="{TemplateBinding ElementFactory}"
Items="{TemplateBinding Columns}" />
</Border>
</ScrollViewer>
<ScrollViewer x:Name="PART_ScrollViewer"
HorizontalScrollBarVisibility="Auto"
BringIntoViewOnFocusChange="{TemplateBinding (ScrollViewer.BringIntoViewOnFocusChange)}">
<TreeDataGridRowsPresenter x:Name="PART_RowsPresenter"
Columns="{TemplateBinding Columns}"
ElementFactory="{TemplateBinding ElementFactory}"
Items="{TemplateBinding Rows}" />
</ScrollViewer>
</DockPanel>
</Border>
</ControlTemplate>
</Setter>

<Style Selector="^ /template/ Border#ColumnHeadersPresenterBorder">
<Setter Property="BorderThickness" Value="0 0 0 1" />
<Setter Property="BorderBrush" Value="{TemplateBinding BorderBrush}" />
</Style>

<Style Selector="^ /template/ ScrollViewer">
<Setter Property="Theme" Value="{StaticResource MaterialModernScrollViewer}" />
</Style>

<!-- Template for classic scrollviewers -->
<Style Selector="^.ClassicScrollViewer /template/ ScrollViewer">
<Setter Property="Theme" Value="{StaticResource MaterialScrollViewer}" />
</Style>

<Style Selector="^.DisableHoveringScrollViewer /template/ ScrollViewer">
<Setter Property="Margin" Value="0" />
<Style Selector="^:horizontal">
<Setter Property="Height" Value="{DynamicResource ScrollBarThickness}" />
</Style>
<Style Selector="^:vertical">
<Setter Property="Height" Value="{DynamicResource ScrollBarThickness}" />
</Style>
</Style>
</ControlTheme>
</ResourceDictionary>
37 changes: 37 additions & 0 deletions Material.Avalonia.TreeDataGrid/TreeDataGridCheckBoxCell.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type TreeDataGridCheckBoxCell}" TargetType="TreeDataGridCheckBoxCell">
<Setter Property="Template">
<ControlTemplate>
<Border x:Name="CellBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}">
<CheckBox x:Name="PART_CheckBox"
IsChecked="{TemplateBinding Value, Mode=TwoWay}"
IsEnabled="{Binding !IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"
IsThreeState="{TemplateBinding IsThreeState}">
<CheckBox.Styles>
<Style Selector="CheckBox /template/ DockPanel#PART_RootPanel">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</CheckBox.Styles>
</CheckBox>
</Border>
</ControlTemplate>
</Setter>

<Style Selector="^">
<Setter Property="Focusable" Value="False" />
<Setter Property="MinWidth" Value="56" />
<Setter Property="Padding" Value="8 6" />
</Style>

<Style Selector="^ /template/ CheckBox#PART_CheckBox">
<Setter Property="Width" Value="40" />
<Setter Property="Padding" Value="0" />
</Style>
</ControlTheme>
</ResourceDictionary>
Loading