Я новичок в 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
Ошибки проверки формы приложения WPF не отображаются в пользовательском интерфейсе ⇐ C#
Место общения программистов C#
1729359810
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;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79105559/in-wpf-app-form-validation-errors-not-showing-up-in-ui[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия