using Common.Messaging; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using MultiTerm.Protocols.Types; using System.Collections.ObjectModel; namespace MultiTerm.Protocols.UsbHid; public partial class UsbHidProtocolSettingsViewModel : ProtocolSettingsViewModel, IUsbHidProtocolSettings { public override ProtocolType ProtocolType => ProtocolType.UsbHid; public ushort VendorId { get; set; } = ushort.MinValue; public ushort ProductId { get; set; } = ushort.MinValue; [ObservableProperty] private string serialNumber = string.Empty; [ObservableProperty] private string vendorIdHex = string.Empty; [ObservableProperty] private string productIdHex = string.Empty; [ObservableProperty] private ObservableCollection devices = new(); [ObservableProperty] private UsbHidDeviceInfo? selectedDevice; [RelayCommand] private void ReloadDevices() { UsbHidDeviceInfo? previouslySelectedDevice = null; // if any device is selected => temporarily store it if (this.SelectedDevice != null) { // shallow copy of the device previouslySelectedDevice = (UsbHidDeviceInfo)this.SelectedDevice.Clone(); } // reload collection this.Devices = new ObservableCollection(UsbHidProtocol.GetDevices()); // select previously selected device again if it still exists if (previouslySelectedDevice != null) { var equalDevices = this.Devices.Where(d => d.Equals(previouslySelectedDevice)); // exactly one match found => take as selected device and quit method if(equalDevices.Count() == 1) { this.SelectedDevice = equalDevices.First(); } } // otherwise select first device, if none is selected yet and there are some available if (this.SelectedDevice == null && this.Devices.Any()) { this.SelectedDevice = this.Devices.First(); } } public UsbHidProtocolSettingsViewModel(IMessenger messenger) : base(messenger) { // load devices initially this.ReloadDevices(); this.SelectedDevice = this.Devices.FirstOrDefault(); } /// /// Updates other fields when was changed. /// /// partial void OnSelectedDeviceChanged(UsbHidDeviceInfo? value) { if(value != null) { this.VendorIdHex = value.VendorId; this.ProductIdHex = value.ProductId; this.SerialNumber = value.SerialNumber; } } public bool AreValid() { // pad left (fill up zeroes) this.VendorIdHex = this.VendorIdHex.PadLeft(4, '0'); if (this.VendorIdHex.Length > 4) { this.messenger.Send(new ProtocolSettingsInvalidUIMessage(nameof(this.VendorId), "Must consist of a maximum of 4 hexadecimal characters")); return false; } if (ushort.TryParse(this.VendorIdHex, System.Globalization.NumberStyles.HexNumber, null, out ushort vendorId) == false) { this.messenger.Send(new ProtocolSettingsInvalidUIMessage(nameof(this.VendorId), "Invalid. Not a 16bit number.")); return false; } // set internal this.VendorId = vendorId; // pad left (fill up zeroes) this.ProductIdHex = this.ProductIdHex.PadLeft(4, '0'); if (this.ProductIdHex.Length > 4) { this.messenger.Send(new ProtocolSettingsInvalidUIMessage(nameof(this.ProductId), "Must consist of a maximum of 4 hexadecimal characters")); return false; } if (ushort.TryParse(this.ProductIdHex, System.Globalization.NumberStyles.HexNumber, null, out ushort productId) == false) { this.messenger.Send(new ProtocolSettingsInvalidUIMessage(nameof(this.ProductId), "Invalid. Not a 16bit number.")); return false; } // set internal this.ProductId = productId; return true; } }