@@ -0,0 +1,22 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Metadata;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation;
|
||||
|
||||
internal class DataTemplateSelector : IDataTemplate
|
||||
{
|
||||
[Content] public Dictionary<Type, IDataTemplate?> Templates { get; } = new();
|
||||
|
||||
public Control? Build(object? param)
|
||||
{
|
||||
if (param is null) return null;
|
||||
var type = param.GetType();
|
||||
return Templates.TryGetValue(type, out var template) ? template?.Build(param) : null;
|
||||
}
|
||||
|
||||
public bool Match(object? data)
|
||||
{
|
||||
return data is IFromItemViewModel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Avalonia.LogicalTree;
|
||||
using Ursa.Controls;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation;
|
||||
|
||||
public class Test
|
||||
{
|
||||
[AvaloniaFact]
|
||||
public void FormItem_Generation()
|
||||
{
|
||||
// Arrange
|
||||
var viewModel = new TestViewModel();
|
||||
viewModel.Items = new ObservableCollection<IFormElement>
|
||||
{
|
||||
new FormTextViewModel { Label = "First Name" },
|
||||
new FormTextViewModel { Label = "Last Name" },
|
||||
new FormAgeViewModel { Label = "Age" },
|
||||
new FormDateRangeViewModel { Label = "Date of Birth" }
|
||||
};
|
||||
var window = new TestWindow { DataContext = viewModel };
|
||||
|
||||
// Act
|
||||
window.Show();
|
||||
|
||||
var form = window.FindControl<Form>("Form");
|
||||
var logicalChildren = form.GetLogicalChildren().ToList();
|
||||
Assert.True(logicalChildren.All(a=>a is FormItem));
|
||||
Assert.IsType<TextBox>(logicalChildren[0].LogicalChildren[0]);
|
||||
Assert.IsType<TextBox>(logicalChildren[1].LogicalChildren[0]);
|
||||
Assert.IsType<NumericUIntUpDown>(logicalChildren[2].LogicalChildren[0]);
|
||||
Assert.IsType<DateRangePicker>(logicalChildren[3].LogicalChildren[0]);
|
||||
Assert.Equal("First Name", FormItem.GetLabel((Control)logicalChildren[0]));
|
||||
Assert.Equal("Last Name", FormItem.GetLabel((Control)logicalChildren[1]));
|
||||
Assert.Equal("Age", FormItem.GetLabel((Control)logicalChildren[2]));
|
||||
Assert.Equal("Date of Birth", FormItem.GetLabel((Control)logicalChildren[3]));
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void FormGroup_Generation()
|
||||
{
|
||||
// Arrange
|
||||
var viewModel = new TestViewModel();
|
||||
viewModel.Items = new ObservableCollection<IFormElement>
|
||||
{
|
||||
new FormGroupViewModel
|
||||
{
|
||||
Title = "Basic Information",
|
||||
Items = new ObservableCollection<IFromItemViewModel>
|
||||
{
|
||||
new FormTextViewModel { Label = "First Name" },
|
||||
new FormTextViewModel { Label = "Last Name" },
|
||||
new FormAgeViewModel { Label = "Age" },
|
||||
new FormDateRangeViewModel { Label = "Date of Birth" }
|
||||
}
|
||||
}
|
||||
};
|
||||
var window = new TestWindow { DataContext = viewModel };
|
||||
|
||||
// Act
|
||||
window.Show();
|
||||
|
||||
var form = window.FindControl<Form>("Form");
|
||||
var logicalChildren = form.GetLogicalChildren().ToList();
|
||||
Assert.True(logicalChildren.All(a=>a is FormGroup));
|
||||
var formGroup = (FormGroup)logicalChildren[0];
|
||||
Assert.Equal("Basic Information", formGroup.Header);
|
||||
var formItems = formGroup.GetLogicalChildren().ToList();
|
||||
Assert.True(formItems.All(a=>a is FormItem));
|
||||
Assert.IsType<TextBox>(formItems[0].LogicalChildren[0]);
|
||||
Assert.IsType<TextBox>(formItems[1].LogicalChildren[0]);
|
||||
Assert.IsType<NumericUIntUpDown>(formItems[2].LogicalChildren[0]);
|
||||
Assert.IsType<DateRangePicker>(formItems[3].LogicalChildren[0]);
|
||||
Assert.Equal("First Name", FormItem.GetLabel((Control)formItems[0]));
|
||||
Assert.Equal("Last Name", FormItem.GetLabel((Control)formItems[1]));
|
||||
Assert.Equal("Age", FormItem.GetLabel((Control)formItems[2]));
|
||||
Assert.Equal("Date of Birth", FormItem.GetLabel((Control)formItems[3]));
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void Mixture_Generation()
|
||||
{
|
||||
// Arrange
|
||||
var viewModel = new TestViewModel();
|
||||
viewModel.Items = new ObservableCollection<IFormElement>
|
||||
{
|
||||
new FormTextViewModel { Label = "First Name" },
|
||||
new FormGroupViewModel
|
||||
{
|
||||
Title = "Basic Information",
|
||||
Items = new ObservableCollection<IFromItemViewModel>
|
||||
{
|
||||
new FormTextViewModel { Label = "Last Name" },
|
||||
new FormAgeViewModel { Label = "Age" },
|
||||
new FormDateRangeViewModel { Label = "Date of Birth" }
|
||||
}
|
||||
}
|
||||
};
|
||||
var window = new TestWindow { DataContext = viewModel };
|
||||
|
||||
// Act
|
||||
window.Show();
|
||||
|
||||
var form = window.FindControl<Form>("Form");
|
||||
var logicalChildren = form.GetLogicalChildren().ToList();
|
||||
Assert.True(logicalChildren.All(a=>a is FormItem || a is FormGroup));
|
||||
Assert.IsType<TextBox>(logicalChildren[0].LogicalChildren[0]);
|
||||
var formGroup = (FormGroup)logicalChildren[1];
|
||||
Assert.Equal("Basic Information", formGroup.Header);
|
||||
var formItems = formGroup.GetLogicalChildren().ToList();
|
||||
Assert.True(formItems.All(a=>a is FormItem));
|
||||
Assert.IsType<TextBox>(formItems[0].LogicalChildren[0]);
|
||||
Assert.IsType<NumericUIntUpDown>(formItems[1].LogicalChildren[0]);
|
||||
Assert.IsType<DateRangePicker>(formItems[2].LogicalChildren[0]);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Irihi.Avalonia.Shared.Contracts;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation;
|
||||
|
||||
public class TestViewModel
|
||||
{
|
||||
public ObservableCollection<IFormElement> Items { get; set; } = [];
|
||||
}
|
||||
|
||||
public interface IFormElement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public interface IFormGroupViewModel : IFormGroup, IFormElement
|
||||
{
|
||||
public string? Title { get; set; }
|
||||
public ObservableCollection<IFromItemViewModel> Items { get; set; }
|
||||
}
|
||||
|
||||
public interface IFromItemViewModel: IFormElement
|
||||
{
|
||||
public string? Label { get; set; }
|
||||
}
|
||||
|
||||
public partial class FormGroupViewModel : ObservableObject, IFormGroupViewModel
|
||||
{
|
||||
[ObservableProperty] private string? _title;
|
||||
public ObservableCollection<IFromItemViewModel> Items { get; set; } = [];
|
||||
}
|
||||
|
||||
public partial class FormTextViewModel : ObservableObject, IFromItemViewModel
|
||||
{
|
||||
[ObservableProperty] private string? _label;
|
||||
[ObservableProperty] private string? _value;
|
||||
}
|
||||
|
||||
public partial class FormAgeViewModel : ObservableObject, IFromItemViewModel
|
||||
{
|
||||
[ObservableProperty] private uint? _age;
|
||||
[ObservableProperty] private string? _label;
|
||||
}
|
||||
|
||||
public partial class FormDateRangeViewModel : ObservableObject, IFromItemViewModel
|
||||
{
|
||||
[ObservableProperty] private DateTime? _end;
|
||||
[ObservableProperty] private string? _label;
|
||||
[ObservableProperty] private DateTime? _start;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:u="https://irihi.tech/ursa"
|
||||
xmlns:vm="clr-namespace:HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation"
|
||||
mc:Ignorable="d" d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
x:DataType="vm:TestViewModel"
|
||||
x:CompileBindings="True"
|
||||
x:Class="HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation.TestWindow"
|
||||
Title="TestWindow">
|
||||
<u:Form Name="Form" ItemsSource="{Binding Items}">
|
||||
<u:Form.Styles>
|
||||
<Style Selector="u|FormGroup"
|
||||
x:DataType="vm:IFormGroupViewModel">
|
||||
<Setter Property="Header"
|
||||
Value="{Binding Title}" />
|
||||
<Setter Property="ItemsSource"
|
||||
Value="{Binding Items}" />
|
||||
</Style>
|
||||
<Style Selector="u|FormItem"
|
||||
x:DataType="vm:IFromItemViewModel">
|
||||
<Setter Property="Label"
|
||||
Value="{Binding Label}" />
|
||||
</Style>
|
||||
</u:Form.Styles>
|
||||
<u:Form.ItemTemplate>
|
||||
<vm:DataTemplateSelector>
|
||||
<DataTemplate
|
||||
x:Key="{x:Type vm:FormTextViewModel}"
|
||||
DataType="vm:FormTextViewModel">
|
||||
<TextBox Text="{Binding Value}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate
|
||||
x:Key="{x:Type vm:FormAgeViewModel}"
|
||||
DataType="vm:FormAgeViewModel">
|
||||
<u:NumericUIntUpDown
|
||||
Value="{Binding Age}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate
|
||||
x:Key="{x:Type vm:FormDateRangeViewModel}"
|
||||
DataType="vm:FormDateRangeViewModel">
|
||||
<u:DateRangePicker
|
||||
SelectedStartDate="{Binding Start}"
|
||||
SelectedEndDate="{Binding End}" />
|
||||
</DataTemplate>
|
||||
</vm:DataTemplateSelector>
|
||||
</u:Form.ItemTemplate>
|
||||
</u:Form>
|
||||
</Window>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation;
|
||||
|
||||
public partial class TestWindow : Window
|
||||
{
|
||||
public TestWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user