This commit is contained in:
Igor Gritsenko 2022-01-24 16:59:45 +03:00
Родитель adf92d1b24
Коммит 905d4e37ad
9 изменённых файлов: 1232 добавлений и 1270 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Input;
@ -25,12 +26,15 @@ public static partial class ControlExtensions
BindingMode? bindingMode, IValueConverter converter, object bindingSource)
where TControl : AvaloniaObject
{
if (sourcePropertyPathString.StartsWith("@") || bindingMode.HasValue)
if (sourcePropertyPathString == null
|| sourcePropertyPathString.StartsWith("@")
|| bindingMode.HasValue
|| bindingSource != default)
{
var path = sourcePropertyPathString.TrimStart('@');
var propertyName = PropertyPathHelper.GetPropertyName(path);
//var path = sourcePropertyPathString.TrimStart('@');
var propertyName = PropertyPathHelper.GetPropertyName(sourcePropertyPathString);
var binding = propertyName == path
var binding = sourcePropertyPathString == null
? new Binding() // if property not set, but only vm itself
: new Binding(propertyName);
@ -146,6 +150,15 @@ public static partial class ControlExtensions
return container;
}
public static TItemsControl Items<TItemsControl>(this TItemsControl container, params Control[] items)
where TItemsControl : ItemsControl
{
if(container.Items is IList itemsCollection)
foreach (var item in items)
itemsCollection.Add(item);
return container;
}
public static TElement With<TElement>(this TElement control, Action<TElement> process)
{
process(control);

Просмотреть файл

@ -6,7 +6,7 @@ public class MagicalSetterGenerator : SetterGeneratorBase
{
public override string GetPropertySetterExtensionOverride(PropertyExtensionInfo info)
{
var argsString = $"{info.ValueTypeSource} value, BindingMode? bindingMode = null, IValueConverter converter = null, object bindingSource = null,"
var argsString = $"{info.ValueTypeSource} value = default, BindingMode? bindingMode = null, IValueConverter converter = null, object bindingSource = null,"
+ $" [CallerArgumentExpression(\"value\")] string ps = null)";
//direct type access
var extensionText =

Просмотреть файл

@ -1,4 +1,7 @@
//this line is required to support Net 6 hot reload for Views
using AvaloniaMarkupSample;
[assembly: System.Reflection.Metadata.MetadataUpdateHandler(typeof(Avalonia.Markup.Declarative.HotReloadManager))]
AppBuilder.Configure<Application>()
@ -6,28 +9,8 @@ AppBuilder.Configure<Application>()
.UseFluentTheme()
.StartWithClassicDesktopLifetime(desktop =>
{
var count = 0;
desktop.MainWindow =
new Window().Ref(out var wnd)
.Content(
new StackPanel().Children(
new Button().Ref(out var button)
.Content("Welcome to Avalonia, please click me!"),
new TextBox().Ref(out var tb1)
.Text("Minimal Declarative Avalonia"),
new TextBox()
.Text(@wnd.Title, BindingMode.TwoWay, bindingSource: wnd),
new Label().Content(
button.OnClick().Select(_ => count++).Select(x => $"You clicked {x} times.").ToBinding()),
new HotReloadView()
))
.Title(tb1.GetObservable(TextBox.TextProperty).Select(x => x.ToUpper()).ToBinding());
//wnd.Topmost = true;
desktop.MainWindow =
new Window()
.Title("Avalonia markup samples")
.Content(new MainView());
}, args);

Просмотреть файл

@ -1,50 +1,77 @@
using Avalonia.Controls.Primitives;
using Avalonia.Markup.Xaml.Templates;
using AvaloniaMarkupSample.MvvmSample;
public class HotReloadView : ViewBase
namespace AvaloniaMarkupSample;
public class MainView : ViewBase
{
protected override object Build() =>
new StackPanel()
.Width(300)
.Children(
new TextBlock()
.Foreground(Brushes.White)
.Padding(12)
.FontSize(30)
.HorizontalAlignment(HorizontalAlignment.Center)
.Text("Hello Hot Reload!"),
new TextBlock()
.Text("Custom control example:"),
new Border()
.BorderBrush(Brushes.Gray)
.BorderThickness(1)
.Child(
new MyCustomControl()
.Margin(20)
new TabControl()
.SelectedIndex(0)
.Items(
new TabItem()
.Header("Hot reload")
.Content(
new Border()
.BorderBrush(Brushes.Gray)
.BorderThickness(1)
.Child(
new TextBlock()
.Padding(12)
.FontSize(30)
.HorizontalAlignment(HorizontalAlignment.Center)
.Text("Hello Hot Reload!")
)
),
new TextBlock()
.Text("Custom templated control example:"),
new Border()
.BorderBrush(Brushes.Gray)
.BorderThickness(1)
.Child(
new MyCustomTemplatedControl()
.Ref(out var myCustomTemplatedControl)
.Margin(20)
.Template(StaticResources.Templates.MyControlTemplate)
new TabItem()
.Header("MVVM")
.Content(
new Border()
.BorderBrush(Brushes.Gray)
.BorderThickness(1)
.Child(
new MvvmSampleView()
)
),
new ToggleButton()
.Ref(out var tb)
.Content("Change template")
.OnClick(args =>
{
myCustomTemplatedControl.Template = !(tb.IsChecked ?? false)
? StaticResources.Templates.MyControlTemplate
: StaticResources.Templates.MyAnotherControlTemplate;
})
);
new TabItem().Header("Custom controls")
.Content(
new StackPanel()
.Width(300)
.Children(
new TextBlock()
.Text("Custom control example:"),
new Border()
.BorderBrush(Brushes.Gray)
.BorderThickness(1)
.Child(
new MyCustomControl()
.Margin(20)
),
new TextBlock()
.Text("Custom templated control example:"),
new Border()
.BorderBrush(Brushes.Gray)
.BorderThickness(1)
.Child(
new MyCustomTemplatedControl()
.Ref(out var myCustomTemplatedControl)
.Margin(20)
.Template(StaticResources.Templates.MyControlTemplate)
),
new ToggleButton()
.Ref(out var tb)
.Content("Change template")
.OnClick(args =>
{
myCustomTemplatedControl.Template = !(tb.IsChecked ?? false)
? StaticResources.Templates.MyControlTemplate
: StaticResources.Templates.MyAnotherControlTemplate;
})
)
));
}

Просмотреть файл

@ -0,0 +1,21 @@
namespace AvaloniaMarkupSample.MvvmSample;
public class MvvmSampleView : ViewBase<MvvmSampleViewModel>
{
protected override void OnCreated()
{
ViewModel = new MvvmSampleViewModel();
}
protected override object Build(MvvmSampleViewModel vm) =>
new StackPanel()
.Children(
new TextBlock()
.Text(@vm.MyProperty),
new Button()
.Content("Execute Command")
.Command(new Binding(nameof(vm.MyCommand)))
.CommandParameter()
);
}

Просмотреть файл

@ -0,0 +1,37 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using JetBrains.Annotations;
namespace AvaloniaMarkupSample.MvvmSample;
public class MvvmSampleViewModel : INotifyPropertyChanged
{
private string _myProperty;
public string MyProperty
{
get => _myProperty;
set
{
if (_myProperty != value)
{
_myProperty = value;
OnPropertyChanged();
}
}
}
public void MyCommand(object? commandParameter)
{
MyProperty = $"You called command with parameter: {commandParameter}";
}
public event PropertyChangedEventHandler? PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

Просмотреть файл

@ -85,7 +85,7 @@
new TextBlock().Text("Enter text:")
.VerticalAlignment(VerticalAlignment.Center),
new TextBox()
.Text(Bind(NewValueProperty))
.Text(@NewValue, BindingMode.TwoWay, bindingSource: this)
.MinWidth(150)
),
@ -98,7 +98,7 @@
new TextBlock().Text("Saved text:")
.VerticalAlignment(VerticalAlignment.Center),
new TextBox()
.Text(Bind(SavedValueProperty))
.Text(@SavedValue, bindingSource: this)
.MinWidth(150)
),
new StackPanel().Row(3)