using HandyControl.Tools.Extension; using System.Collections.ObjectModel; using YY.Admin.Core; using YY.Admin.Core.Entity; using YY.Admin.Core.Services; namespace YY.Admin.ViewModels.WeightRecord; public class MixerMaterialPickerDialogViewModel : BaseViewModel, IDialogResultable { private readonly IMixerMaterialService _mixerMaterialService; private string? _searchCode; public string? SearchCode { get => _searchCode; set => SetProperty(ref _searchCode, value); } private string? _searchName; public string? SearchName { get => _searchName; set => SetProperty(ref _searchName, value); } public ObservableCollection Materials { get; } = new(); public IReadOnlyList SelectedMaterials => Materials.Where(m => m.IsSelected).ToList(); public int SelectedCount => Materials.Count(m => m.IsSelected); public string SelectedDisplayText { get { var names = Materials.Where(m => m.IsSelected).Select(m => m.Source.MaterialName).ToList(); return names.Count == 0 ? "请在上方列表中勾选物料,可多选" : string.Join(";", names); } } public bool HasSelectedMaterials => Materials.Any(m => m.IsSelected); private bool _result; public bool Result { get => _result; set => SetProperty(ref _result, value); } public Action? CloseAction { get; set; } public DelegateCommand SearchCommand { get; } public DelegateCommand ConfirmCommand { get; } public DelegateCommand CancelCommand { get; } public DelegateCommand ClearSelectionCommand { get; } public MixerMaterialPickerDialogViewModel( IMixerMaterialService mixerMaterialService, IContainerExtension container, IRegionManager regionManager) : base(container, regionManager) { _mixerMaterialService = mixerMaterialService; SearchCommand = new DelegateCommand(async () => await LoadAsync()); ConfirmCommand = new DelegateCommand(Confirm, () => HasSelectedMaterials); CancelCommand = new DelegateCommand(() => CloseAction?.Invoke()); ClearSelectionCommand = new DelegateCommand(ClearSelection); _ = LoadAsync(); } private async Task LoadAsync() { try { IsLoading = true; var selectedIds = Materials.Where(m => m.IsSelected).Select(m => m.Source.Id).ToHashSet(); var result = await _mixerMaterialService.PageAsync(1, 500, materialCode: SearchCode?.Trim(), materialName: SearchName?.Trim()); Materials.Clear(); foreach (var mat in result.Records) { var item = new SelectableMixerMaterial(mat); if (selectedIds.Contains(mat.Id)) item.IsSelected = true; item.SelectionChanged += NotifySelectionChanged; Materials.Add(item); } NotifySelectionChanged(); } catch { Materials.Clear(); } finally { IsLoading = false; } } private void NotifySelectionChanged() { RaisePropertyChanged(nameof(SelectedCount)); RaisePropertyChanged(nameof(SelectedDisplayText)); RaisePropertyChanged(nameof(HasSelectedMaterials)); ConfirmCommand.RaiseCanExecuteChanged(); } private void ClearSelection() { foreach (var m in Materials) m.IsSelected = false; } private void Confirm() { if (!HasSelectedMaterials) return; Result = true; CloseAction?.Invoke(); } public class SelectableMixerMaterial : System.ComponentModel.INotifyPropertyChanged { public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged; public event Action? SelectionChanged; private bool _isSelected; public bool IsSelected { get => _isSelected; set { if (_isSelected == value) return; _isSelected = value; PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(nameof(IsSelected))); SelectionChanged?.Invoke(); } } public MesMixerMaterial Source { get; } public SelectableMixerMaterial(MesMixerMaterial source) => Source = source; } }