Свойство ExpandoObject с привязкой к данным не будет обновляться в динамическом XAML.C#

Место общения программистов C#
Anonymous
Свойство ExpandoObject с привязкой к данным не будет обновляться в динамическом XAML.

Сообщение Anonymous »

Я создаю приложение AvaloniaUI с помощью набора инструментов сообщества MVVM, где мне нужно динамически отображать элементы управления и привязывать их к данным модели представления, свойства которой будут неизвестны до момента выполнения. Фактически, я буду читать свойства и поля, к которым они должны быть привязаны, из файла JSON.
В качестве доказательства концепции я написал это небольшое приложение для тестирования этих динамических привязок. Я пытаюсь использовать ExpandoObject для инкапсуляции тех динамических свойств, к которым я привязываюсь к динамически создаваемым элементам управления. К сожалению, ни одно динамически созданное свойство не обновляется в соответствии со своим динамически созданным полем.
Мое главное окно содержит: Его код программной части обрабатывает нажатие кнопки, создавая экземпляр для группы настроек, создавая динамические элементы управления и добавляя его для отображения:

Код: Выделить всё

using Avalonia.Controls;
using DynamicBindingControls.ViewModels;

namespace DynamicBindingControls.Views {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}

private void btnCreateDynamicControls_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) {
var dynaSettings = new DynamicSettingsGroup();
dynaSettings.DataContext = new DynamicSettingsGroupVM("Dynamism!");
dynaSettings.CreateDynamicSettings();
stpSettingsGroups.Children.Add(dynaSettings);
}
}
}
Управление группой настроек имеет текстовый блок, привязанный к определенному свойству модели представления, и пространство, в которое можно добавлять динамические поля: Его код программной части создает динамическое поле, которое он добавляет в свою StackPanel, которое должно быть привязано к его свойству модели представления:

Код: Выделить всё

using Avalonia.Controls;
using Avalonia.Data;
using System.Collections.Generic;

namespace DynamicBindingControls.Views;

public partial class DynamicSettingsGroup : UserControl {
public DynamicSettingsGroup() {
InitializeComponent();
}

public void CreateDynamicSettings() {
var myDC = DataContext as ViewModels.DynamicSettingsGroupVM;

// Use string indexing to add properties to the ExpandoObject
var props = myDC.DynamicSettingsProperties as IDictionary;
props["DynaProp"] = "Brand new";
var settingField = new TextBox {
[!TextBox.TextProperty] = new Binding("DynamicSettingsProperties.DynaProp")
};

stpDynamicFields.Children.Add(settingField);
}
}
Его модель представления должна обрабатывать изменения динамического поля:

Код: Выделить всё

using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Dynamic;

namespace DynamicBindingControls.ViewModels;

public partial class DynamicSettingsGroupVM : ViewModelBase {
[ObservableProperty]
private string _name;
public dynamic DynamicSettingsProperties { get; set;  } = new ExpandoObject();

public DynamicSettingsGroupVM(string aName) {
Name = aName;
((INotifyPropertyChanged)DynamicSettingsProperties).PropertyChanged +=
new PropertyChangedEventHandler(HandlePropertyChanges);
}

private void HandlePropertyChanges(
object? sender, PropertyChangedEventArgs e) {
var dict = DynamicSettingsProperties as IDictionary;
Trace.WriteLine($"{e.PropertyName} has changed to {dict[e.PropertyName]}.");
}
}
Поэтому после запуска нажатие кнопки добавляет группу настроек, каждая со статическим и динамическим полем с привязкой к данным, а также журналы отладки:

Код: Выделить всё

DynaProp has changed to Brand new.
[Binding]An error occurred binding 'Text' to 'DynamicSettingsProperties.DynaProp' at 'DynaProp': 'Could not find a matching property accessor for 'DynaProp' on 'System.Dynamic.ExpandoObject'.' (TextBox #1589866)
Но это начальное значение никогда не отображается — динамическое поле выглядит совершенно пустым — и ничего не выводится, когда динамическому полю присваивается новое значение, поэтому я знаю, что динамически добавляемое изменение свойства ExpandoObject не слышно.
Изображение

Все помощь оценена по достоинству.

Вернуться в «C#»