DE CODE
sgcUI in een Avalonia 12-venster
Elk fragment is gekopieerd uit het voorbeeld AvaloniaProAlternative, een Avalonia 12-app op net8.0 met gecompileerde bindings en FluentTheme, die in Release compileert voor de geregistreerde en Community-edities met 0 waarschuwingen in de demo en zijn zelftest doorstaat. Hier staat geen Avalonia Pro-code: deze pagina toont alleen code die is gecompileerd.
Eén XAML-voorvoegsel voor elk product
Elke sgcUI Avalonia-assembly koppelt zijn besturingselementen aan één namespace-URI, dus één voorvoegsel sgc dekt ze allemaal, naast de standaardnamespace van Avalonia:
MainWindow.axaml<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sgc="https://www.esegece.com/sgcui"
xmlns:vm="using:sgcUIAvaloniaPro"
x:Class="sgcUIAvaloniaPro.MainWindow"
x:DataType="vm:TMainViewModel"
Title="sgcUI next to Avalonia 12: the controls Avalonia Pro does not ship" Width="1240" Height="820">
Niet vermeld op de Avalonia Pro-pagina: scheduler en Kanban over één takenlijst
Beide weergaven binden aan dezelfde collectie Tasks van het view model. TsgcAvaloniaPlannerItemFields koppelt de leden van je eigen taakklasse, en een sleepactie in beide weergaven schrijft Begin, End of Stage terug naar de taak:
MainWindow.axaml<sgc:TsgcAvaloniaScheduler x:Name="scheduler" ItemsSource="{Binding Tasks}"
ResourcesSource="{Binding People}" SelectedItem="{Binding Selected}">
<sgc:TsgcAvaloniaScheduler.ItemFields>
<sgc:TsgcAvaloniaPlannerItemFields IdField="Key" TitleField="Name" StartField="Begin"
FinishField="End" ResourcesField="Owner" StatusField="Stage"/>
</sgc:TsgcAvaloniaScheduler.ItemFields>
<sgc:TsgcAvaloniaScheduler.ResourceFields>
<sgc:TsgcAvaloniaPlannerResourceFields IdField="Code" NameField="Label"/>
</sgc:TsgcAvaloniaScheduler.ResourceFields>
</sgc:TsgcAvaloniaScheduler>
<sgc:TsgcAvaloniaKanban x:Name="kanban" Grid.Row="1" Margin="0,8,0,0" ColumnSource="pkcList"
ItemsSource="{Binding Tasks}" ResourcesSource="{Binding People}"
SelectedItem="{Binding Selected}">
<sgc:TsgcAvaloniaKanban.ItemFields>
<sgc:TsgcAvaloniaPlannerItemFields IdField="Key" TitleField="Name" StartField="Begin"
FinishField="End" ResourcesField="Owner" StatusField="Stage"/>
</sgc:TsgcAvaloniaKanban.ItemFields>
<sgc:TsgcAvaloniaKanban.ResourceFields>
<sgc:TsgcAvaloniaPlannerResourceFields IdField="Code" NameField="Label"/>
</sgc:TsgcAvaloniaKanban.ResourceFields>
<sgc:TsgcAvaloniaKanban.Columns>
<sgc:TsgcAvaloniaKanbanColumn StatusId="todo" Caption="To do"/>
<sgc:TsgcAvaloniaKanbanColumn StatusId="doing" Caption="In progress"/>
<sgc:TsgcAvaloniaKanbanColumn StatusId="done" Caption="Done"/>
</sgc:TsgcAvaloniaKanban.Columns>
</sgc:TsgcAvaloniaKanban>
Niet vermeld: een dashboard met KPI-kaarten en een grafiek
Tegels op een raster van 12 kolommen, elk met een KPI-kaart of een willekeurig besturingselement, gebonden aan het view model:
MainWindow.axaml<sgc:TsgcAvaloniaDashboard x:Name="dashboard" Columns="12" RowHeight="110">
<sgc:TsgcAvaloniaDashboardTile Title="Revenue" Col="0" Row="0" ColSpan="4" RowSpan="2">
<sgc:TsgcAvaloniaKPICard x:Name="kpiRevenue" Title="Revenue this month" Value="{Binding Revenue}"
Trend="ktUp" FooterText="all channels"/>
</sgc:TsgcAvaloniaDashboardTile>
<sgc:TsgcAvaloniaDashboardTile Title="Orders" Col="4" Row="0" ColSpan="4" RowSpan="2">
<sgc:TsgcAvaloniaKPICard x:Name="kpiOrders" Title="Orders" Value="{Binding Orders}"
Trend="ktUp" FooterText="this month"/>
</sgc:TsgcAvaloniaDashboardTile>
<sgc:TsgcAvaloniaDashboardTile Title="Support" Col="8" Row="0" ColSpan="4" RowSpan="2">
<sgc:TsgcAvaloniaKPICard x:Name="kpiTickets" Title="Open tickets" Value="{Binding Tickets}"
Trend="ktDown" FooterText="help desk"/>
</sgc:TsgcAvaloniaDashboardTile>
<sgc:TsgcAvaloniaDashboardTile Title="Visits per day" Col="0" Row="2" ColSpan="12" RowSpan="3">
<sgc:TsgcAvaloniaChart x:Name="chartVisits">
<sgc:TsgcAvaloniaChartSeries ItemsSource="{Binding Visits}" XMember="Time" YMember="Value"
Title="Visits" Color="#FF16A34A"/>
<sgc:TsgcAvaloniaChart.Axes>
<sgc:TsgcAvaloniaChartAxis Name="X" AxisType="catDateTime"/>
<sgc:TsgcAvaloniaChartAxis Name="Y" Title="Visits"/>
</sgc:TsgcAvaloniaChart.Axes>
</sgc:TsgcAvaloniaChart>
</sgc:TsgcAvaloniaDashboardTile>
</sgc:TsgcAvaloniaDashboard>
Ook in Avalonia Pro: grid, grafiek, PDF-viewer en rich text
Wanneer je een overlappend besturingselement vervangt, verandert de weergave en blijft het view model. Het grid met gedeclareerde kolommen en een tweerichtings-SelectedItem:
MainWindow.axaml<sgc:TsgcAvaloniaGrid x:Name="grid" x:DataType="vm:TGridViewModel" Margin="8"
ItemsSource="{Binding Customers}" SelectedItem="{Binding Selected}"
KeyMember="Id" AutoGenerateColumns="False">
<sgc:TsgcAvaloniaGridColumn FieldName="Id" Caption="Id" Width="60" DataType="gdtInteger"/>
<sgc:TsgcAvaloniaGridColumn FieldName="Name" Caption="Customer" Width="220"/>
<sgc:TsgcAvaloniaGridColumn FieldName="City" Caption="City" Width="140"/>
<sgc:TsgcAvaloniaGridColumn FieldName="Balance" Caption="Balance" Width="130" DataType="gdtFloat"
DisplayFormat="#,##0.00" Alignment="gaRight"/>
</sgc:TsgcAvaloniaGrid>
Een lijngrafiek over een datum-tijdas:
MainWindow.axaml<sgc:TsgcAvaloniaChart x:Name="chartPrice" x:DataType="vm:TChartViewModel" Margin="8">
<sgc:TsgcAvaloniaChartSeries ItemsSource="{Binding Prices}" XMember="Time" YMember="Value"
Title="Price" Color="#FF2563EB"/>
<sgc:TsgcAvaloniaChart.Axes>
<sgc:TsgcAvaloniaChartAxis Name="X" AxisType="catDateTime" Title="Time"/>
<sgc:TsgcAvaloniaChartAxis Name="Y" Title="Price"/>
</sgc:TsgcAvaloniaChart.Axes>
</sgc:TsgcAvaloniaChart>
Een PDF-viewer met miniaturen, gebonden aan een TsgcPDFDocument van het view model:
MainWindow.axaml<sgc:TsgcAvaloniaPDFThumbnailView x:Name="pdfThumbs" Viewer="{Binding #pdfViewer}"/>
<sgc:TsgcAvaloniaPDFViewer x:Name="pdfViewer" Grid.Column="1" Margin="8,0,0,0"
Document="{Binding Document}" ZoomMode="zmFitWidth"/>
Het view model bouwt het document met sgcPDF, slaat het in het geheugen op en parseert het terug, zoals een uit een bestand gelezen document de viewer bereikt:
ViewModels\TOverlapViewModels.cs// a three page A4 report written with sgcPDF, saved to memory and parsed back,
// the way a document read from a file or a stream reaches the viewer
private static TsgcPDFDocument DoBuild()
{
byte[] vBytes;
using (TsgcPDFDocument oWriter = new TsgcPDFDocument())
{
for (int i = 1; i <= CS_PAGES; i++)
{
TsgcPDFPage oPage = oWriter.AddPage(595, 842);
oPage.DrawRectangleFill(0, 772, 595, 70, 0.12, 0.23, 0.54);
oPage.DrawTextColor("Quarterly report, page " + i + " of " + CS_PAGES, 50, 800,
TsgcPDFStandardFont.sfHelveticaBold, 20, 1, 1, 1);
oPage.DrawText("Built in code with sgcPDF (TsgcPDFDocument) and shown by TsgcAvaloniaPDFViewer.", 50,
730, TsgcPDFStandardFont.sfHelvetica, 12);
oPage.DrawText("Search, zoom, thumbnails and text selection work on it like on any PDF file.", 50,
710, TsgcPDFStandardFont.sfHelvetica, 12);
for (int k = 0; k < 6; k++)
oPage.DrawRectangleFill(60 + k * 80, 420, 50, 40 + ((i * 3 + k * 5) % 9) * 25, 0.15, 0.39, 0.92);
oPage.DrawRectangle(40, 40, 515, 712, 1.0);
}
using (MemoryStream oStream = new MemoryStream())
{
oWriter.SaveToStream(oStream);
vBytes = oStream.ToArray();
}
}
TsgcPDFDocument vResult = new TsgcPDFDocument();
vResult.LoadFromBytes(vBytes);
return vResult;
}
De rich-texteditor, gebonden als Markdown-tekst (sgcRichEdit is alleen geregistreerd):
Views\RichEditTab.axaml<sgc:TsgcAvaloniaRichEdit x:Name="richEdit" Margin="8" DocumentFormat="refMarkdown"
DocumentText="{Binding Text}"/>
ViewModels\TOverlapViewModels.cspublic sealed class TRichTextViewModel : TViewModelBase
{
private string FText =
"# Release notes\n\nThe **sgcRichEdit** control is bound to this view model through " +
"*DocumentText* in Markdown.\n\n- Styles, lists and tables\n- Links such as " +
"[www.esegece.com](https://www.esegece.com)\n- HTML, RTF, Markdown and JSON in and out\n";
/// <summary>The document as Markdown (DocumentFormat="refMarkdown"), written back on focus loss.</summary>
public string Text
{
get { return FText; }
set { DoSet(ref FText, value, "Text"); }
}
}
Het thema blijft waar het is
De applicatie behoudt FluentTheme. De sgcUI-besturingselementen volgen de themavariant ervan, licht, donker of de instelling van het besturingssysteem, en schakelen live mee met de Fluent-besturingselementen:
Program.cspublic override void Initialize()
{
// the existing host theme stays: the sgcUI controls follow its theme variant
Styles.Add(new FluentTheme());
RequestedThemeVariant = ThemeVariant.Default;
}
ViewModels\TOverlapViewModels.cs/// <summary>0 Follow host (RequestedThemeVariant Default), 1 Light, 2 Dark. The sgcUI controls
/// follow the Avalonia theme variant of the FluentTheme host (ThemeFollow utfHost).</summary>
public int ModeIndex
{
get { return FModeIndex; }
set
{
if (value < 0 || value > 2 || !DoSet(ref FModeIndex, value, "ModeIndex"))
return;
sgcUIApplication.ThemeFollow = TsgcUIThemeFollow.utfHost;
sgcUIApplication.SetTheme(TsgcUITheme.utDefault);
if (Application.Current != null)
Application.Current.RequestedThemeVariant = value == 1 ? ThemeVariant.Light :
value == 2 ? ThemeVariant.Dark : ThemeVariant.Default;
}
}