init
This commit is contained in:
@@ -0,0 +1,481 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using DTS.Common.Events;
|
||||
using DTS.Common.Events.TTSImport;
|
||||
using DTS.Common.Interface.DataRecorders;
|
||||
using DTS.Common.Interface.TestSetups.Imports.TTS.DIChannels;
|
||||
using DTS.Common.Interface.TestSetups.Imports.TTS.ReadFile;
|
||||
using Prism.Events;
|
||||
using Unity;
|
||||
using DTS.Common.Interactivity;
|
||||
using Prism.Regions;
|
||||
using Prism.Commands;
|
||||
using TTSImport.Model;
|
||||
using TTSImport.Resources;
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace TTSImport
|
||||
{
|
||||
/// <summary>
|
||||
/// this class handles Level Trigger edit/create functionality
|
||||
/// </summary>
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class DigitalInputChannelsViewModel : IDigitalInputChannelsViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The Hardware Scan view
|
||||
/// </summary>
|
||||
public IDigitalInputChannelsView View { get; set; }
|
||||
|
||||
private IEventAggregator _eventAggregator { get; }
|
||||
private IRegionManager _regionManager;
|
||||
private IUnityContainer UnityContainer { get; }
|
||||
|
||||
public InteractionRequest<Notification> NotificationRequest { get; }
|
||||
public InteractionRequest<Confirmation> ConfirmationRequest { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the TechnologyDomainEditViewModel.
|
||||
/// </summary>
|
||||
/// <param name="view">The IDigitalInputChannelsView.</param>
|
||||
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
|
||||
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
|
||||
/// <param name="unityContainer">The unityContainer.</param>
|
||||
public DigitalInputChannelsViewModel(IDigitalInputChannelsView view, IRegionManager regionManager,
|
||||
IEventAggregator eventAggregator, IUnityContainer unityContainer)
|
||||
{
|
||||
View = view;
|
||||
View.DataContext = this;
|
||||
|
||||
NotificationRequest = new InteractionRequest<Notification>();
|
||||
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
||||
|
||||
_eventAggregator = eventAggregator;
|
||||
UnityContainer = unityContainer;
|
||||
_regionManager = regionManager;
|
||||
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
||||
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
|
||||
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
|
||||
_eventAggregator.GetEvent<AssignedChannelsChangedEvent>().Subscribe(OnAssignedChannelsChangedEvent,
|
||||
ThreadOption.PublisherThread, true);
|
||||
_eventAggregator.GetEvent<TTSImportHardwareScanFinishedEvent>()
|
||||
.Subscribe(OnHardwareScanComplete, ThreadOption.PublisherThread, true);
|
||||
}
|
||||
|
||||
#region Methods
|
||||
private void OnHardwareScanComplete(List<IDASHardware> hardware)
|
||||
{
|
||||
_hardware = hardware;
|
||||
}
|
||||
|
||||
private void OnAssignedChannelsChangedEvent(ITTSSetup setup)
|
||||
{
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
OnAssignedChannelsChangedEvent(setup);
|
||||
}));
|
||||
return;
|
||||
}
|
||||
_setup = setup;
|
||||
if (null == _hardware || null == _setup) { return; }
|
||||
var channels = new ObservableCollection<DASChannel>();
|
||||
var remainingChannels = new ObservableCollection<ITTSChannelRecord>();
|
||||
var channelIdToChannelRecord = new Dictionary<string, DASChannel>();
|
||||
foreach (var das in _hardware)
|
||||
{
|
||||
var ichannels = das.GetIHardwareChannels();
|
||||
foreach (var ch in ichannels)
|
||||
{
|
||||
if (!ch.IsDigitalIn) { continue; }
|
||||
var newChannel = new DASChannel(ch);
|
||||
channels.Add(newChannel);
|
||||
channelIdToChannelRecord[ch.GetId()] = newChannel;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var channelRecord in _setup.Channels)
|
||||
{
|
||||
if (channelRecord.IsEmptyRecord)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!channelRecord.IsDigitalInput)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!channelRecord.IsChannelCodeValid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (channelRecord.ChannelCode == TTSChannelRecord.NONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (null != channelRecord.HardwareChannel &&
|
||||
channelIdToChannelRecord.ContainsKey(channelRecord.HardwareChannel.GetId()))
|
||||
{
|
||||
channelIdToChannelRecord[channelRecord.HardwareChannel.GetId()].SetITTSChannelRecord(channelRecord);
|
||||
}
|
||||
else
|
||||
{
|
||||
remainingChannels.Add(channelRecord);
|
||||
}
|
||||
}
|
||||
|
||||
DASChannels = channels;
|
||||
RemainingChannels = remainingChannels;
|
||||
OnPropertyChanged("DASChannels");
|
||||
OnPropertyChanged("RemainingChannels");
|
||||
}
|
||||
public void Cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
public Task CleanupAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void Initialize(object parameter)
|
||||
{
|
||||
}
|
||||
|
||||
public void Initialize(object parameter, object model)
|
||||
{
|
||||
}
|
||||
|
||||
public Task InitializeAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task InitializeAsync(object parameter)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Activated()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private Event handler for RaiseNotification event.
|
||||
/// </summary>
|
||||
private void OnBusyIndicatorNotification(bool eventArg)
|
||||
{
|
||||
IsBusy = eventArg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private Event handler for RaiseNotification event.
|
||||
/// </summary>
|
||||
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
|
||||
{
|
||||
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
|
||||
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
|
||||
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, "",
|
||||
eventArgsWithTitle.Image, string.Empty);
|
||||
|
||||
NotificationRequest.Raise(new Notification
|
||||
{
|
||||
Content = eventArgsWithoutTitle,
|
||||
Title = eventArgsWithTitle.Title
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
private ITTSSetup _setup;
|
||||
private IList<IDASHardware> _hardware;
|
||||
public bool IsDirty { get; private set; }
|
||||
private bool _isBusy;
|
||||
|
||||
public bool IsBusy
|
||||
{
|
||||
get => _isBusy;
|
||||
set
|
||||
{
|
||||
_isBusy = value;
|
||||
OnPropertyChanged("IsBusy");
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isMenuIncluded;
|
||||
|
||||
public bool IsMenuIncluded
|
||||
{
|
||||
get => _isMenuIncluded;
|
||||
set
|
||||
{
|
||||
_isMenuIncluded = value;
|
||||
OnPropertyChanged("IsMenuIncluded");
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isNavigationIncluded;
|
||||
|
||||
public bool IsNavigationIncluded
|
||||
{
|
||||
get => _isNavigationIncluded;
|
||||
set
|
||||
{
|
||||
_isNavigationIncluded = value;
|
||||
OnPropertyChanged("IsNavigationIncluded");
|
||||
}
|
||||
}
|
||||
public bool AssignEnabled { get; set; }
|
||||
public bool RemoveEnabled { get; set; }
|
||||
public bool EnableOrDisableEnabled { get; set; }
|
||||
public ObservableCollection<DASChannel> DASChannels { get; set; } = new ObservableCollection<DASChannel>();
|
||||
public ObservableCollection<ITTSChannelRecord> RemainingChannels { get; set; } =
|
||||
new ObservableCollection<ITTSChannelRecord>();
|
||||
|
||||
private ITTSChannelRecord _selectedRemainingChannel;
|
||||
public ITTSChannelRecord SelectedRemainingChannel
|
||||
{
|
||||
get => _selectedRemainingChannel;
|
||||
set
|
||||
{
|
||||
_selectedRemainingChannel = value;
|
||||
if (null == _selectedRemainingChannel || null == SelectedDASChannel) return;
|
||||
AssignEnabled = true;
|
||||
OnPropertyChanged("AssignEnabled");
|
||||
}
|
||||
}
|
||||
private DASChannel _selectedDASChannel;
|
||||
public DASChannel SelectedDASChannel
|
||||
{
|
||||
get => _selectedDASChannel;
|
||||
set
|
||||
{
|
||||
_selectedDASChannel = value;
|
||||
DetermineRemoveEnableStatus();
|
||||
}
|
||||
}
|
||||
private void DetermineRemoveEnableStatus()
|
||||
{
|
||||
if (_selectedDASChannel?.Channel != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_selectedDASChannel.EID) &&
|
||||
_selectedDASChannel.EID == _selectedDASChannel.Channel.SensorEID)
|
||||
{
|
||||
//can only be replaced, can't be removed
|
||||
RemoveEnabled = false;
|
||||
}
|
||||
RemoveEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveEnabled = false;
|
||||
}
|
||||
OnPropertyChanged("RemoveEnabled");
|
||||
AssignEnabled = null != _selectedDASChannel && null != _selectedRemainingChannel;
|
||||
OnPropertyChanged("AssignEnabled");
|
||||
EnableOrDisableEnabled = _selectedDASChannel?.Channel != null;
|
||||
OnPropertyChanged("EnableOrDisableEnabled");
|
||||
OnPropertyChanged("EnableOrDisableText");
|
||||
}
|
||||
public string EnableOrDisableText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SelectedDASChannel?.Channel == null)
|
||||
{
|
||||
return StringResources.Analog_Enable;
|
||||
}
|
||||
return SelectedDASChannel.Channel.Disabled
|
||||
? StringResources.Analog_Enable
|
||||
: StringResources.Analog_Disable;
|
||||
}
|
||||
}
|
||||
#endregion Properties
|
||||
|
||||
#region Commands
|
||||
#region assign
|
||||
/// <summary>
|
||||
/// Assign a channel code to a channel
|
||||
/// </summary>
|
||||
private DelegateCommand _assignCommand;
|
||||
public DelegateCommand AssignCommand => _assignCommand ?? (_assignCommand = new DelegateCommand(Assign));
|
||||
private void Assign()
|
||||
{
|
||||
if (SelectedRemainingChannel == null) { return; }
|
||||
|
||||
_eventAggregator.GetEvent<TTSImportTestSetupChangedEvent>().Publish(_setup);
|
||||
//BEFORE we go any further, check the state of sensor ids
|
||||
//if the channel has a sensor id AND there's a sensor on the channel with the same id
|
||||
//then prompt on replacing the id
|
||||
//IF the channel has a sensor id and there's no sensor on the channel BUT the new sensor has a different id
|
||||
//then prompt on replacing the id
|
||||
var bReplacingID = false;
|
||||
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
|
||||
{
|
||||
if (null != SelectedRemainingChannel && SelectedRemainingChannel.SensorEID != SelectedDASChannel.EID)
|
||||
{
|
||||
bReplacingID = true;
|
||||
}
|
||||
//if existing channel has this ID, we will need to clear out the old id and assign a new one...
|
||||
if (null != SelectedDASChannel.Channel && SelectedDASChannel.Channel.SensorEID == SelectedDASChannel.EID)
|
||||
{
|
||||
bReplacingID = true;
|
||||
}
|
||||
}
|
||||
if (bReplacingID)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var dialogResult = MessageBox.Show(StringResources.AssignSensorPrompt, StringResources.UserFeedbackRequired, MessageBoxButton.YesNo);
|
||||
if (dialogResult == MessageBoxResult.Yes)
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(AssignWork));
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
AssignWork();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// assigns a channel record to a physical channel
|
||||
/// </summary>
|
||||
private void AssignWork()
|
||||
{
|
||||
if (null != SelectedDASChannel.Channel)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
|
||||
{
|
||||
SelectedDASChannel.Channel.SensorEID = "";
|
||||
}
|
||||
RemainingChannels.Add(SelectedDASChannel.Channel);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
|
||||
{
|
||||
SelectedRemainingChannel.SensorEID = SelectedDASChannel.EID;
|
||||
}
|
||||
|
||||
SelectedRemainingChannel.DigitalInputMode = DTS.Common.Enums.DigitalInputModes.CCNO;
|
||||
SelectedDASChannel.SetITTSChannelRecord(SelectedRemainingChannel);
|
||||
|
||||
var channel = SelectedRemainingChannel;
|
||||
var index = RemainingChannels.IndexOf(channel);
|
||||
SelectedRemainingChannel = null;
|
||||
RemainingChannels.Remove(channel);
|
||||
CollectionViewSource.GetDefaultView(DASChannels)?.Refresh();
|
||||
if (index < RemainingChannels.Count)
|
||||
{
|
||||
SelectedRemainingChannel = RemainingChannels[index];
|
||||
OnPropertyChanged("SelectedRemainingChannel");
|
||||
}
|
||||
else if (RemainingChannels.Count > 0)
|
||||
{
|
||||
SelectedRemainingChannel = RemainingChannels[index - 1];
|
||||
OnPropertyChanged("SelectedRemainingChannel");
|
||||
}
|
||||
index = DASChannels.IndexOf(SelectedDASChannel);
|
||||
for (var i = index; i < DASChannels.Count; i++)
|
||||
{
|
||||
var dasChannel = DASChannels[i];
|
||||
if (null != dasChannel.Channel) { continue; }
|
||||
SelectedDASChannel = dasChannel;
|
||||
OnPropertyChanged("SelectedDASChannel");
|
||||
return;
|
||||
}
|
||||
//didn't find a match, start from the beginning?
|
||||
for (var i = 0; i < index; i++)
|
||||
{
|
||||
var dasChannel = DASChannels[i];
|
||||
if (null != dasChannel.Channel)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SelectedDASChannel = dasChannel;
|
||||
OnPropertyChanged("SelectedDASChannel");
|
||||
return;
|
||||
}
|
||||
//if we get here there's no new channel to go to, but we need to set the remove/enable/disable button status
|
||||
OnPropertyChanged("SelectedDASChannel");
|
||||
DetermineRemoveEnableStatus();
|
||||
}
|
||||
#endregion
|
||||
#region remove
|
||||
private DelegateCommand _removeCommand;
|
||||
public DelegateCommand RemoveCommand => _removeCommand ?? (_removeCommand = new DelegateCommand(Remove));
|
||||
/// <summary>
|
||||
/// remove a hardware channel assignment (does not remove the channel from the test setup though?)
|
||||
/// </summary>
|
||||
private void Remove()
|
||||
{
|
||||
if (null == SelectedDASChannel || null == SelectedDASChannel.Channel) { return; }
|
||||
_eventAggregator.GetEvent<TTSImportTestSetupChangedEvent>().Publish(_setup);
|
||||
RemainingChannels.Add(SelectedDASChannel.Channel);
|
||||
SelectedDASChannel.SetITTSChannelRecord(null);
|
||||
CollectionViewSource.GetDefaultView(DASChannels)?.Refresh();
|
||||
var index = DASChannels.IndexOf(SelectedDASChannel);
|
||||
for (var i = index; i < DASChannels.Count; i++)
|
||||
{
|
||||
if (null == DASChannels[i].Channel) { continue; }
|
||||
SelectedDASChannel = DASChannels[i];
|
||||
OnPropertyChanged("SelectedDASChannel");
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < index; i++)
|
||||
{
|
||||
if (null == DASChannels[i].Channel) { continue; }
|
||||
SelectedDASChannel = DASChannels[i];
|
||||
OnPropertyChanged("SelectedDASChannel");
|
||||
return;
|
||||
}
|
||||
//if we get here there's no new channel to go to, but we need to set the remove/enable/disable button status
|
||||
OnPropertyChanged("SelectedDASChannel");
|
||||
DetermineRemoveEnableStatus();
|
||||
}
|
||||
#endregion
|
||||
#region enableordisable
|
||||
private DelegateCommand _enableOrDisableCommand;
|
||||
public DelegateCommand EnableOrDisableCommand =>
|
||||
_enableOrDisableCommand ?? (_enableOrDisableCommand = new DelegateCommand(EnableOrDisable));
|
||||
/// <summary>
|
||||
/// enables or disables a channel in the test.
|
||||
/// </summary>
|
||||
private void EnableOrDisable()
|
||||
{
|
||||
if (SelectedDASChannel?.Channel == null) { return; }
|
||||
SelectedDASChannel.Channel.Disabled = !SelectedDASChannel.Channel.Disabled;
|
||||
SelectedDASChannel.Disabled = SelectedDASChannel.Channel.Disabled;
|
||||
|
||||
OnPropertyChanged("EnableOrDisableText");
|
||||
_eventAggregator.GetEvent<TTSImportTestSetupChangedEvent>().Publish(_setup);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Occurs when a property value changes.
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user