On property changed implemented on viewBase

This commit is contained in:
Igor Gritsenko 2022-11-02 01:13:30 +03:00
Родитель ca9a2bf12e
Коммит b2b080379a
4 изменённых файлов: 80 добавлений и 5 удалений

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

@ -203,7 +203,7 @@ public static class ControlPropertyExtensions
public static TElement Styles<TElement>(this TElement control, params Style[] styles)
where TElement : Control
{
foreach (var style in styles)
foreach (var style in styles)
control.Styles.Add(style);
return control;

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

@ -0,0 +1,40 @@
using System;
using System.Reflection;
namespace Avalonia.Markup.Declarative
{
internal class ViewPropertyState
{
private object _value;
public string Name { get; }
private PropertyInfo PropertyInfo { get; }
private ViewBase View { get; }
public ViewPropertyState(PropertyInfo propertyInfo, ViewBase view)
{
this.PropertyInfo = propertyInfo;
this.View = view;
this.Name = propertyInfo.Name;
_value = PropertyInfo.GetValue(View);
}
public bool CheckStateChangedAndUpdate()
{
var oldValue = _value;
_value = PropertyInfo.GetValue(View);
if (_value == null && oldValue != null)
return false;
if (_value != null && oldValue == null)
return false;
return
(_value == null && oldValue == null)
|| (_value != null && !_value.Equals(oldValue));
}
}
}

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

@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
@ -62,7 +65,7 @@ public abstract class ViewBase<TViewModel> : ViewBase
/// <summary>
/// Base view class used like UserControl in XAML
/// </summary>
public abstract class ViewBase : Decorator, IReloadable
public abstract class ViewBase : Decorator, IReloadable, INotifyPropertyChanged
{
public event Action ViewInitialized;
@ -110,6 +113,8 @@ public abstract class ViewBase : Decorator, IReloadable
{
try
{
InitStateMembers();
var content = Build();
Child = content as Control;
@ -194,6 +199,34 @@ public abstract class ViewBase : Decorator, IReloadable
return asset;
}
ViewPropertyState[]? _propertyStates = null;
private void InitStateMembers()
{
var viewType = GetType();
_propertyStates = viewType
.GetProperties()
.Where(p => p.DeclaringType == viewType)
.Select(p => new ViewPropertyState(p, this))
.ToArray();
}
protected void StateHasChnaged()
{
if (_propertyStates == null)
return;
foreach (var prop in _propertyStates)
if (prop.CheckStateChangedAndUpdate())
OnPropertyChanged(prop.Name);
}
public new event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#region Hot reload stuff
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)

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

@ -6,17 +6,19 @@ public class MvuSampleView : ViewBase
new StackPanel()
.Children(
new TextBlock()
.Text(@MyProperty),
.Text(@MyProperty, bindingSource: this),
new Button()
.Content("Click me")
.Content("Click me " + @MyProperty1)
.OnClick(OnButtonClick)
);
public string MyProperty { get; set; } = "Hello MVU";
public string MyProperty1 { get; set; } = "No changes";
private void OnButtonClick(RoutedEventArgs obj)
{
throw new NotImplementedException();
MyProperty = "Button was clicked!";
StateHasChnaged();
}
}