Ошибки проверки формы приложения WPF не отображаются в пользовательском интерфейсеC#

Место общения программистов C#
Ответить
Anonymous
 Ошибки проверки формы приложения WPF не отображаются в пользовательском интерфейсе

Сообщение Anonymous »

Я новичок в WPF, и мне нужно создать небольшое приложение на .NET8, генерирующее текстовые файлы. В пользовательском интерфейсе я хочу иметь два обязательных поля, одно из которых принимает только числа больше 0. Я использовал плавную проверку, подход mvvm и использовал INotifyDataErrorInfo вместе с INotifyPropertyChanged в моей модели представления. Я хочу, чтобы проверка происходила при нажатии кнопки, потере фокуса и т. д. Когда я отлаживаю решение, я получаю ошибки проверки в словаре, но они не отображаются в пользовательском интерфейсе. Я надеюсь, что какая-нибудь добрая душа подскажет мне, что может быть не так.
Модель:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABCText.FileGeneratorUI.Models
{
public class TargetFile : INotifyPropertyChanged
{

private string _size;
private string _fileName;
public string Size
{
get => _size;
set
{
_size = value;
OnPropertyChanged(nameof(Size));
}
}

public string FileName
{
get => _fileName;
set
{
_fileName = value;
OnPropertyChanged(nameof(FileName));
}
}

public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Модель представления
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ABCText.FileGeneratorUI.Models;
using ABCText.FileGeneratorUI.Validation;
using FluentValidation.Results;

namespace ABCText.FileGeneratorUI.ViewModels
{
public class MainViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
private TargetFile _targetFile;
private readonly TargetFileValidator _validator;
private Dictionary _validationErrors = new Dictionary();

public MainViewModel()
{
_targetFile = new TargetFile();
_validator = new TargetFileValidator();
_targetFile.PropertyChanged += OnTargetFilePropertyChanged;
}

public TargetFile TargetFile
{
get => _targetFile;
set
{
if (_targetFile != null)
_targetFile.PropertyChanged -= OnTargetFilePropertyChanged;

_targetFile = value;

if (_targetFile != null)
_targetFile.PropertyChanged += OnTargetFilePropertyChanged;

OnPropertyChanged(nameof(TargetFile));
Validate();
}
}

public bool HasErrors => _validationErrors.Any();

public void Validate()
{
var validationResult = _validator.Validate(_targetFile);
_validationErrors.Clear();

if (!validationResult.IsValid)
{
foreach (var error in validationResult.Errors)
{
if (!_validationErrors.ContainsKey(error.PropertyName))
_validationErrors.Add(error.PropertyName, new List());

_validationErrors[error.PropertyName].Add(error.ErrorMessage);

ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(error.PropertyName));
}

}

}

protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void OnTargetFilePropertyChanged(object? sender, PropertyChangedEventArgs e)
{
Validate();
}

public IEnumerable GetErrors(string? propertyName)
{
return _validationErrors.TryGetValue(propertyName ?? string.Empty, out var errors) ? errors : null;
}

public event PropertyChangedEventHandler? PropertyChanged;
public event EventHandler? ErrorsChanged;
}
}

Представление (xaml):





































































Вид (код):
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ABCText.FileGeneratorUI.ViewModels;
using ABCText.FileGeneratorUI.Models;

namespace ABCText.FileGeneratorUI.Views
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}

private void GenerateButton_Click(object sender, RoutedEventArgs e)
{
if (this.DataContext is MainViewModel viewModel)
{
viewModel.Validate();
}
}
}
}

Валидатор:
using ABCText.FileGeneratorUI.Models;
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABCText.FileGeneratorUI.Validation
{
public class TargetFileValidator : AbstractValidator
{
public TargetFileValidator()
{
RuleFor(x => x.Size)
.NotEmpty().WithMessage("Field file size is required.")
.Must(IsIntegerNumberGreaterThanZero).WithMessage("Field must be a number greater than 0.");

RuleFor(x => x.FileName)
.NotEmpty().WithMessage("Field file name is required");
}

private bool IsIntegerNumberGreaterThanZero(string value) => int.TryParse(value, out var result) && result > 0;

}
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... g-up-in-ui
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

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