Перейти к содержанию

Создание пользовательского обьекта

Для примера создадим плагин с диаграммой, которая отображает результат испытаний, а именно количество изделий, прошедших испытание и количество бракованных изделий.

Для визуального отображения необходимо загрузить дополнительные пакеты:

  • Avalonia: Avalonia, Avalonia.Desktop, Avalonia.Themes.Fluent
  • LiveChartsCore.SkiaSharpView.Avalonia - для отображения диаграммы
  • CommunityToolkit.Mvvm - для реализации шаблона проектирования MVVM

Эти пакеты доступны в стандартном репозитории nuget.org.

Класс Model

Класс Model отвечает за бизнес логику. Создадим для него отдельный класс:

namespace Test.Plugin.Models
{
    [CustomType("[GUID]", Category = "Test")]
    public class TestResult : IECustomTypeBase
    {
        public double Passed { get; set; } = 100.0;
        public double Failed { get; set; } = 45.0;

        public TestResult(double passed, double failed)
        {
            Passed = passed;
            Failed = failed;
        }

        //наличие конструктора без параметров обязательно!
        public TestResult() { }

        public override string ToString()
        {
            return $"Passed: {Passed}, Failed = {Failed}";
        }

        //Clone и Dispose - реализация интерфейса IECustomTypeBase
        public object Clone()
        {
            return new TestResult(Passed, Failed);
        }

        public void Dispose() { }
    }
}

Класс ViewModel

Класс ViewModel отвечает за обмен информацией между внутренней моделью (Model) и внешним представлением (View).

namespace Test.Plugin.ViewModels
{
    [CustomTypeViewModel("[GUID]", typeof(TestResult))]
    //для корректной работы класс должен быть публичным и разбитым (partial)
    public partial class TestResultViewModel : ObservableObject
    {
        private readonly TestResult _testResult;

        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(PassedValues))]
        private double _passed;

        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(FailedValues))]
        private double _failed;

        public double[] PassedValues => [Passed];

        public double[] FailedValues => [Failed];

        public TestResultViewModel(TestResult testResult)
        {
            _testResult = testResult;

            Passed = _testResult.Passed;
            Failed = _testResult.Failed;
        }

        partial void OnPassedChanged(double value)
        {
            _testResult.Passed = value;
        }

        partial void OnFailedChanged(double value)
        {
            _testResult.Failed = value;
        }
    }
}

Класс View

Для создания этого класса необходимо создать 2 файла: один непосредоственно описывает View, второй - инициализирует первый.

Файл описания View .axaml

<UserControl 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:models="using:Test.Plugins.Models"
             xmlns:viewmodels="using:Test.Plugin.ViewModels"
             mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="300"
             xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.Avalonia;assembly=LiveChartsCore.SkiaSharpView.Avalonia"
             x:Class="Test.Plugin.Views.TestResultView"
             x:DataType="viewmodels:TestResultViewModel"
             Width="400"
             Height="300"
             Name="UserControl">
    <Grid RowDefinitions="Auto, *" Background="WhiteSmoke">
        <StackPanel Grid.Row="0" Margin="24,24,24,24" Spacing="5">
            <TextBlock Text="Пройдено:"/>
            <NumericUpDown Value="{Binding Passed}"/>
            <TextBlock Text="Брак:"/>
            <NumericUpDown Value="{Binding Failed}"/>
        </StackPanel>

        <lvc:PieChart Grid.Row="1"
                Margin="24,0,24,0"
                FontFamily="Segoe UI"
                Background="WhiteSmoke">
            <lvc:PieChart.Series>
                <lvc:XamlPieSeries
                    SeriesName="Пройдено"
                    Values="{Binding PassedValues}"
                    MaxRadialColumnWidth="60"
                    Fill="{lvc:SolidColorPaint Color='008000'}"/>
                <lvc:XamlPieSeries
                    SeriesName="Брак"
                    Values="{Binding FailedValues}"
                    MaxRadialColumnWidth="60"/>
            </lvc:PieChart.Series>
        </lvc:PieChart>
    </Grid>
</UserControl>

Файл инициализации .cs

namespace Test.Plugin.Views;

[CustomTypeView("[GUID]", typeof(TestResultViewModel))]
//обязательно разбитый (partial) для сборки с Avalonia
public partial class TestResultView : UserControl
{
    public TestResultView()
    {
        //функция становится доступна после сборки проекта
        InitializeComponent();
    }
}

Загрузить готовый проект из статьи