using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows.Data; using System.Windows.Input; namespace XLAB2 { internal sealed class SelectInstrumentTypeWindowViewModel : ObservableObject { private string _searchText; private AvailableInstrumentItem _selectedType; private string _serialNumbersText; private string _statusText; public SelectInstrumentTypeWindowViewModel(string customerName, IReadOnlyList instrumentTypes) { CustomerName = customerName ?? string.Empty; InstrumentTypes = new ObservableCollection(instrumentTypes ?? new List()); InstrumentTypesView = CollectionViewSource.GetDefaultView(InstrumentTypes); InstrumentTypesView.Filter = FilterTypes; ConfirmCommand = new RelayCommand(Confirm, CanConfirm); CancelCommand = new RelayCommand(Cancel); UpdateStatus(); } public event EventHandler CloseRequested; public ICommand CancelCommand { get; private set; } public ICommand ConfirmCommand { get; private set; } public string CustomerName { get; private set; } public ObservableCollection InstrumentTypes { get; private set; } public ICollectionView InstrumentTypesView { get; private set; } public string SearchText { get { return _searchText; } set { if (SetProperty(ref _searchText, value)) { InstrumentTypesView.Refresh(); UpdateStatus(); } } } public AvailableInstrumentItem SelectedType { get { return _selectedType; } set { if (SetProperty(ref _selectedType, value)) { ((RelayCommand)ConfirmCommand).RaiseCanExecuteChanged(); UpdateStatus(); } } } public string SerialNumbersText { get { return _serialNumbersText; } set { if (SetProperty(ref _serialNumbersText, value)) { ((RelayCommand)ConfirmCommand).RaiseCanExecuteChanged(); UpdateStatus(); } } } public string StatusText { get { return _statusText; } private set { SetProperty(ref _statusText, value); } } public InstrumentTypeSelectionResult GetResult() { var serialNumbers = ParseSerialNumbers(SerialNumbersText); return SelectedType == null ? null : new InstrumentTypeSelectionResult { TypeItem = SelectedType, SerialNumbers = serialNumbers }; } private void Cancel(object parameter) { RaiseCloseRequested(false); } private bool CanConfirm(object parameter) { return SelectedType != null && ParseSerialNumbers(SerialNumbersText).Count > 0; } private void Confirm(object parameter) { RaiseCloseRequested(true); } private bool FilterTypes(object item) { var instrumentType = item as AvailableInstrumentItem; if (instrumentType == null) { return false; } if (string.IsNullOrWhiteSpace(SearchText)) { return true; } return Contains(instrumentType.RegistryNumber, SearchText) || Contains(instrumentType.InstrumentName, SearchText) || Contains(instrumentType.InstrumentType, SearchText) || Contains(instrumentType.RangeText, SearchText) || Contains(instrumentType.AccuracyText, SearchText) || Contains(instrumentType.MeasurementArea, SearchText); } private static bool Contains(string source, string searchText) { return !string.IsNullOrWhiteSpace(source) && source.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0; } private static List ParseSerialNumbers(string value) { var serialNumbers = new List(); var unique = new HashSet(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrWhiteSpace(value)) { return serialNumbers; } var separators = new[] { '\r', '\n', '\t', ',', ';' }; foreach (var token in value.Split(separators, StringSplitOptions.RemoveEmptyEntries)) { var serialNumber = token.Trim(); if (serialNumber.Length == 0 || !unique.Add(serialNumber)) { continue; } serialNumbers.Add(serialNumber); } return serialNumbers; } private void RaiseCloseRequested(bool? dialogResult) { var handler = CloseRequested; if (handler != null) { handler(this, dialogResult); } } private void UpdateStatus() { var visibleCount = InstrumentTypesView.Cast().Count(); var serialCount = ParseSerialNumbers(SerialNumbersText).Count; StatusText = string.Format( "Всего типов: {0}. По фильтру: {1}. Выбран тип: {2}. Уникальных зав. №: {3}.", InstrumentTypes.Count, visibleCount, SelectedType == null ? "нет" : "да", serialCount); } } }