Error handling system added

This commit is contained in:
retr0volkov
2025-07-05 17:31:02 +03:00 Unverified
parent 8806d28787
commit de8c487f92
21 changed files with 339 additions and 17 deletions
+1
View File
@@ -6,6 +6,7 @@
<entry key="App.axaml" value="GazpromApp.csproj" />
<entry key="Views/EditEquipmentDialog.axaml" value="GazpromApp.csproj" />
<entry key="Views/EditPointDialog.axaml" value="GazpromApp.csproj" />
<entry key="Views/ErrorView.axaml" value="GazpromApp.csproj" />
<entry key="Views/ImageView.axaml" value="GazpromApp.csproj" />
<entry key="Views/MainWindow.axaml" value="GazpromApp.csproj" />
<entry key="Views/NewEquipmentDialog.axaml" value="GazpromApp.csproj" />
+8
View File
@@ -0,0 +1,8 @@
namespace GazpromApp.Enums;
public enum ErrorSeverity
{
Message = 0,
Warning = 1,
Error = 2
}
+9
View File
@@ -0,0 +1,9 @@
using CommunityToolkit.Mvvm.Messaging.Messages;
using GazpromApp.ViewModels;
namespace GazpromApp.Messages;
public class ErrorMessage(ErrorViewModel error) : AsyncRequestMessage<ErrorViewModel?>
{
public ErrorViewModel Error { get; } = error;
}
+11
View File
@@ -0,0 +1,11 @@
using GazpromApp.Enums;
using GazpromApp.ViewModels;
namespace GazpromApp.Models;
public class Error
{
public string? Title { get; set; }
public string? Message { get; set; }
public ErrorSeverity Severity { get; set; }
}
+69
View File
@@ -0,0 +1,69 @@
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GazpromApp.Enums;
using GazpromApp.Models;
namespace GazpromApp.ViewModels;
public partial class ErrorViewModel : ViewModelBase
{
[ObservableProperty]
private string? _title;
[ObservableProperty]
private string? _message;
[RelayCommand]
private static void Ok(Window w)
{
w.Close();
}
private ErrorSeverity severity;
// Visual and other properties
[ObservableProperty] private bool _isErrorVisible;
[ObservableProperty] private bool _isWarnVisible;
[ObservableProperty] private bool _isInfoVisible;
public ErrorViewModel()
{
IsInfoVisible = true;
Title = "Тест ошибки";
Message = "Сообщение ошибки";
}
public ErrorViewModel(Error error)
{
Title = error.Title;
Message = error.Message;
severity = error.Severity;
switch (error.Severity)
{
case ErrorSeverity.Error:
IsErrorVisible = true;
break;
case ErrorSeverity.Warning:
IsWarnVisible = true;
break;
case ErrorSeverity.Message:
IsInfoVisible = true;
break;
default:
IsInfoVisible = true;
break;
}
}
public Error GetError()
{
Error error = new Error()
{
Title = Title,
Message = Message,
Severity = severity,
};
return error;
}
}
+18 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
using Avalonia.Controls;
@@ -7,6 +8,7 @@ using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using GazpromApp.Enums;
using GazpromApp.Messages;
using GazpromApp.Models;
@@ -57,8 +59,23 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
IsImageSelected = files.Count > 0;
try
{
Image = IsImageSelected ? new ImageViewModel(new Models.Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(files[0].Path.AbsolutePath)) } : null;
}
catch (ArgumentException)
{
Error error = new Error()
{
Title = "Ошибка обработки картинки",
Message = "Картинка не была добавлена",
Severity = ErrorSeverity.Error,
};
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
IsImageSelected = false;
}
}
[RelayCommand]
private async Task ViewImage()
+18 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
@@ -10,6 +11,7 @@ using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using GazpromApp.Enums;
using GazpromApp.Messages;
using GazpromApp.Models;
using GazpromApp.Views;
@@ -59,7 +61,22 @@ public partial class EditPointDialogViewModel : ViewModelBase
FileTypeFilter = [FilePickerFileTypes.ImageAll],
});
foreach (var file in files)
{
try
{
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath) ) });
}
catch (ArgumentException)
{
Error error = new Error()
{
Title = "Ошибка обработки картинки",
Message = $"Картинка не была добавлена: \"{HttpUtility.UrlDecode(file.Name)}\"",
Severity = ErrorSeverity.Error,
};
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
}
}
IsImagesEmpty = Images.Count == 0;
}
+18 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
using Avalonia.Controls;
@@ -7,6 +8,7 @@ using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using GazpromApp.Enums;
using GazpromApp.Messages;
using GazpromApp.Models;
@@ -37,8 +39,23 @@ public partial class NewEquipmentDialogViewModel : ViewModelBase
IsImageSelected = files.Count > 0;
try
{
Image = IsImageSelected ? new ImageViewModel(new Models.Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(files[0].Path.AbsolutePath)) } : null;
}
catch (ArgumentException)
{
Error error = new Error()
{
Title = "Ошибка обработки картинки",
Message = "Картинка не была добавлена",
Severity = ErrorSeverity.Error,
};
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
IsImageSelected = false;
}
}
[RelayCommand]
private void DeleteImage()
+20 -1
View File
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
@@ -9,7 +11,9 @@ using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using GazpromApp.Enums;
using GazpromApp.Messages;
using GazpromApp.Models;
using Image = GazpromApp.Models.Image;
using Point = GazpromApp.Models.Point;
@@ -37,7 +41,22 @@ public partial class NewPointDialogViewModel : ViewModelBase
FileTypeFilter = [FilePickerFileTypes.ImageAll],
});
foreach (var file in files)
{
try
{
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath)) });
}
catch (ArgumentException)
{
Error error = new Error()
{
Title = "Ошибка обработки картинки",
Message = $"Картинка не была добавлена: \"{HttpUtility.UrlDecode(file.Name)}\"",
Severity = ErrorSeverity.Error,
};
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
}
}
IsImagesEmpty = Images.Count == 0;
}
+11
View File
@@ -30,6 +30,16 @@ public partial class EditEquipmentDialog : Window
m.Reply(dialog.ShowDialog<ImageViewModel?>(w));
});
// error handling
WeakReferenceMessenger.Default.Register<EditEquipmentDialog, ErrorMessage>(this, static (w, m) =>
{
ErrorView dialog = new ErrorView()
{
DataContext = m.Error
};
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
});
// new property dialog
// edit property dialog
@@ -50,6 +60,7 @@ public partial class EditEquipmentDialog : Window
private void Window_OnClosed(object? sender, EventArgs e)
{
WeakReferenceMessenger.Default.Unregister<ViewImageMessage>(this);
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
//
//
WeakReferenceMessenger.Default.Unregister<EditEquipmentDone>(this);
+39 -4
View File
@@ -28,9 +28,20 @@ public partial class EditPointDialog : Window
m.Reply(dialog.ShowDialog<ImageViewModel?>(w));
});
// new equipment
WeakReferenceMessenger.Default.Register<EditPointDialog, NewEquipmentMessage>(this, static (w, m) =>
// error
WeakReferenceMessenger.Default.Register<EditPointDialog, ErrorMessage>(this, static (w, m) =>
{
ErrorView dialog = new ErrorView()
{
DataContext = m.Error
};
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
});
// new equipment
WeakReferenceMessenger.Default.Register<EditPointDialog, NewEquipmentMessage>(this, (w, m) =>
{
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
NewEquipmentDialog dialog = new NewEquipmentDialog()
{
DataContext = new NewEquipmentDialogViewModel()
@@ -42,6 +53,7 @@ public partial class EditPointDialog : Window
WeakReferenceMessenger.Default.Register<EditPointDialog, EditEquipmentMessage>(this, (w, m) =>
{
WeakReferenceMessenger.Default.Unregister<ViewImageMessage>(this);
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
EditEquipmentDialog dialog = new EditEquipmentDialog()
{
DataContext = new EditEquipmentDialogViewModel(m.Equipment)
@@ -49,8 +61,21 @@ public partial class EditPointDialog : Window
m.Reply(dialog.ShowDialog<EquipmentViewModel?>(w));
});
// re registering view image
WeakReferenceMessenger.Default.Register<EditPointDialog, EditEquipmentDone>(this, (w, m) =>
// re registering error when new equipment done
WeakReferenceMessenger.Default.Register<EditPointDialog, NewEquipmentDone>(this, (_, _) =>
{
WeakReferenceMessenger.Default.Register<EditPointDialog, ErrorMessage>(this, static (w, m) =>
{
ErrorView dialog = new ErrorView()
{
DataContext = m.Error
};
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
});
});
// re registering view image and error view
WeakReferenceMessenger.Default.Register<EditPointDialog, EditEquipmentDone>(this, (_, _) =>
{
WeakReferenceMessenger.Default.Register<EditPointDialog, ViewImageMessage>(this, static (w, m) =>
{
@@ -60,6 +85,15 @@ public partial class EditPointDialog : Window
};
m.Reply(dialog.ShowDialog<ImageViewModel?>(w));
});
WeakReferenceMessenger.Default.Register<EditPointDialog, ErrorMessage>(this, static (w, m) =>
{
ErrorView dialog = new ErrorView()
{
DataContext = m.Error
};
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
});
});
// new property
@@ -82,6 +116,7 @@ public partial class EditPointDialog : Window
private void Window_OnClosed(object? sender, EventArgs e)
{
WeakReferenceMessenger.Default.Unregister<ViewImageMessage>(this);
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
WeakReferenceMessenger.Default.Unregister<NewEquipmentMessage>(this);
WeakReferenceMessenger.Default.Unregister<EditEquipmentMessage>(this);
// new prop
+44
View File
@@ -0,0 +1,44 @@
<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:vm="using:GazpromApp.ViewModels"
x:Name="Window"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="180"
Width="400" Height="180"
x:Class="GazpromApp.Views.ErrorView"
x:DataType="vm:ErrorViewModel"
Title="{Binding Title}"
Icon="/Assets/ic_fluent_error_circle_24_filled (1) (Custom).png"
WindowStartupLocation="CenterOwner"
Closing="Window_OnClosing"
Closed="Window_OnClosed">
<Design.DataContext>
<vm:ErrorViewModel/>
</Design.DataContext>
<Grid x:Name="Root" Margin="16"
ColumnDefinitions="50, *" RowDefinitions="50, *, Auto">
<Image Grid.Row="0" Grid.Column="0"
IsVisible="{Binding IsErrorVisible}"
Source="avares://GazpromApp/Assets/ic_fluent_error_circle_24_filled (Custom).png"/>
<Image Grid.Row="0" Grid.Column="0"
IsVisible="{Binding IsWarnVisible}"
Source="avares://GazpromApp/Assets/ic_fluent_warning_24_filled (Custom).png"/>
<Image Grid.Row="0" Grid.Column="0"
IsVisible="{Binding IsInfoVisible}"
Source="avares://GazpromApp/Assets/ic_fluent_info_24_filled (Custom).png"/>
<Panel Grid.Row="0" Grid.Column="1" Grid.RowSpan="2">
<StackPanel Margin="8">
<TextBlock Text="{Binding Title}" FontSize="20" MaxLines="2" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Message}" MaxLines="3" TextWrapping="Wrap"/>
</StackPanel>
</Panel>
<Panel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="ОК"
Command="{Binding OkCommand}"
CommandParameter="{Binding #Window}"/>
</StackPanel>
</Panel>
</Grid>
</Window>
+29
View File
@@ -0,0 +1,29 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace GazpromApp.Views;
public partial class ErrorView : Window
{
public ErrorView()
{
InitializeComponent();
if (Design.IsDesignMode)
return;
}
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
{
}
private void Window_OnClosed(object? sender, EventArgs e)
{
}
}
+13
View File
@@ -2,6 +2,7 @@
using Avalonia.Controls;
using CommunityToolkit.Mvvm.Messaging;
using GazpromApp.Messages;
using GazpromApp.ViewModels;
namespace GazpromApp.Views;
@@ -11,14 +12,26 @@ public partial class NewEquipmentDialog : Window
{
InitializeComponent();
// done entering new equipment
WeakReferenceMessenger.Default.Register<NewEquipmentDialog, NewEquipmentDone>(this, static (w, m) =>
{
w.Close(m.Equipment);
});
// register to work with errors
WeakReferenceMessenger.Default.Register<NewEquipmentDialog, ErrorMessage>(this, static (w, m) =>
{
ErrorView dialog = new ErrorView()
{
DataContext = m.Error
};
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
});
}
private void Window_OnClosed(object? sender, EventArgs e)
{
WeakReferenceMessenger.Default.Unregister<NewEquipmentDone>(this);
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
}
}
+2 -1
View File
@@ -10,7 +10,8 @@
x:DataType="vm:NewPointDialogViewModel"
Title="Создание нового объекта"
Icon="/Assets/ic_fluent_home_add_24_filled (Custom).png"
WindowStartupLocation="CenterOwner">
WindowStartupLocation="CenterOwner"
Closed="Window_OnClosed">
<Design.DataContext>
<vm:NewPointDialogViewModel/>
</Design.DataContext>
+19 -1
View File
@@ -1,6 +1,8 @@
using Avalonia.Controls;
using System;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.Messaging;
using GazpromApp.Messages;
using GazpromApp.ViewModels;
namespace GazpromApp.Views;
@@ -10,9 +12,25 @@ public partial class NewPointDialog : Window
{
InitializeComponent();
// done entering new point
WeakReferenceMessenger.Default.Register<NewPointDialog, NewPointDone>(this, static (w, m) =>
{
w.Close(m.Point);
});
// register to work with errors
WeakReferenceMessenger.Default.Register<NewPointDialog, ErrorMessage>(this, static (w, m) =>
{
ErrorView dialog = new ErrorView()
{
DataContext = m.Error
};
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
});
}
private void Window_OnClosed(object? sender, EventArgs e)
{
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
}
}
@@ -1 +1 @@
41a928e641efcd3e89b584959a8b8be084763735298d1e3a4ead534f873c57ec
c7763810c7c9fe86f032a444db49dfe85bfa277e9aa1a02ca59b8891c1bb6265
Binary file not shown.
+1 -1
View File
@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("GazpromApp")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+c0178625cd3b6493e3edb6c1847a526192a67b27")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8806d287870ff52e89394ebf3740eb9130b2fa6c")]
[assembly: System.Reflection.AssemblyProductAttribute("GazpromApp")]
[assembly: System.Reflection.AssemblyTitleAttribute("GazpromApp")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
@@ -1 +1 @@
bd707ac6740d23b45223f7c5e6320a05563f812a5bd2e1dc1b2ba3f2023ec0f2
fca2f4a4c1933f8850b7151879ad727af085b4f7d1499d3a22126a355fadba2d
@@ -38,6 +38,9 @@ build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
[D:/RiderProjects/GazpromApp/Views/EditPointDialog.axaml]
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
[D:/RiderProjects/GazpromApp/Views/ErrorView.axaml]
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
[D:/RiderProjects/GazpromApp/Views/ImageView.axaml]
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml