init
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
using DTS.Common.Base;
|
||||
|
||||
namespace DTS.Common.Interface
|
||||
{
|
||||
public interface ITestSettingsViewModel : IBaseViewModel { }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<Style x:Key="CheckBoxFocusVisual">
|
||||
<Setter Property="Control.Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Border>
|
||||
<Rectangle
|
||||
Margin="15,0,0,0"
|
||||
StrokeThickness="1"
|
||||
Stroke="#60000000"
|
||||
StrokeDashArray="1 2"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="{x:Type CheckBox}" TargetType="CheckBox">
|
||||
<Setter Property="SnapsToDevicePixels" Value="true"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="FontFamily" Value="{DynamicResource MetroFontRegular}"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckBoxFocusVisual}"/>
|
||||
<Setter Property="Foreground" Value="#999999"/>
|
||||
<Setter Property="Background" Value="#3f3f3f"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="CheckBox">
|
||||
<BulletDecorator Background="Transparent">
|
||||
<BulletDecorator.Bullet>
|
||||
<Border x:Name="Border"
|
||||
Width="13"
|
||||
Height="13"
|
||||
CornerRadius="0"
|
||||
Background="#3f3f3f"
|
||||
BorderBrush="#999999"
|
||||
BorderThickness="1">
|
||||
<Path
|
||||
Width="7" Height="7"
|
||||
x:Name="CheckMark"
|
||||
SnapsToDevicePixels="False"
|
||||
Stroke="#979797"
|
||||
StrokeThickness="2"
|
||||
Data="M 0 0 L 7 7 M 0 7 L 7 0" />
|
||||
</Border>
|
||||
</BulletDecorator.Bullet>
|
||||
<ContentPresenter Margin="8,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left"
|
||||
RecognizesAccessKey="True"/>
|
||||
</BulletDecorator>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="false">
|
||||
<Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="{x:Null}">
|
||||
<Setter TargetName="CheckMark" Property="Data" Value="M 0 7 L 7 0" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter TargetName="Border" Property="Background" Value="#454545" />
|
||||
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ApplicationAccentBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Foreground" Value="#c1c1c1"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,359 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.Hardware;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Classes.Hardware
|
||||
{
|
||||
public class DASMonitorInfo : IDASMonitorInfo
|
||||
{
|
||||
public string SerialNumber { get; private set; }
|
||||
|
||||
public double[] TiltSensorCals { get; private set; } = new double[18];
|
||||
|
||||
public short[] TiltSensorDataPre { get; private set; } = new short[3];
|
||||
|
||||
public DFConstantsAndEnums.TiltAxes TiltAxes { get; private set; } = DFConstantsAndEnums.TiltAxes.IXIYIZ;
|
||||
|
||||
public int AxisIgnored { get; private set; }
|
||||
|
||||
public double MountOffsetAxisOne { get; private set; } = double.NaN;
|
||||
|
||||
public double MountOffsetAxisTwo { get; private set; } = double.NaN;
|
||||
|
||||
private string[] _channelNames = new string[0];
|
||||
|
||||
public string GetChannelName(int index)
|
||||
{
|
||||
if (index >= _channelNames.Length) { return $"{Strings.Strings.Ch}#{1 + index:00}"; }
|
||||
return _channelNames[index];
|
||||
}
|
||||
|
||||
private double[] _offsetTolerancesHigh = new double[6];
|
||||
public double GetOffsetTolerancemVHigh(int index)
|
||||
{
|
||||
if (index >= _offsetTolerancesHigh.Length) { return 0D; }
|
||||
return _offsetTolerancesHigh[index];
|
||||
}
|
||||
|
||||
private double[] _offsetTolerancesLow = new double[6];
|
||||
public double GetOffsetTolerancemVLow(int index)
|
||||
{
|
||||
if (index >= _offsetTolerancesLow.Length) { return 0D; }
|
||||
return _offsetTolerancesLow[index];
|
||||
}
|
||||
|
||||
public void ReadFromFile(string path)
|
||||
{
|
||||
if(!File.Exists(path)) { return; }
|
||||
try
|
||||
{
|
||||
var lines = File.ReadAllLines(path);
|
||||
var keys = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
for (var i = 0; i < lines.Length && i < keys.Length; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
var key = keys[i];
|
||||
switch (key)
|
||||
{
|
||||
case Fields.SerialNumber:
|
||||
SerialNumber = line;
|
||||
break;
|
||||
case Fields.TiltSensorCals:
|
||||
TiltSensorCals = ToDoubleArray(line);
|
||||
break;
|
||||
case Fields.TiltSensorDataPre:
|
||||
TiltSensorDataPre = ToShortArray(line);
|
||||
break;
|
||||
case Fields.TiltAxes:
|
||||
TiltAxes = (DFConstantsAndEnums.TiltAxes)Enum.Parse(typeof(DFConstantsAndEnums.TiltAxes), line);
|
||||
break;
|
||||
case Fields.AxesIgnored:
|
||||
AxisIgnored = int.Parse(line, CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.MountOffsetAxisOne:
|
||||
MountOffsetAxisOne = double.Parse(line, CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.MountOffsetAxisTwo:
|
||||
MountOffsetAxisTwo = double.Parse(line, CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.ChannelNames:
|
||||
_channelNames = ToStringArray(line);
|
||||
break;
|
||||
case Fields.OffsetTolerancesLow:
|
||||
_offsetTolerancesLow = ToDoubleArray(line);
|
||||
break;
|
||||
case Fields.OffsetTolerancesHigh:
|
||||
_offsetTolerancesHigh = ToDoubleArray(line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
private short [] ToShortArray(string line)
|
||||
{
|
||||
var shorts = new List<short>();
|
||||
var tokens = line.Split(new[] { SEPARATOR }, StringSplitOptions.None);
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (short.TryParse(line, NumberStyles.Any, CultureInfo.InvariantCulture, out var s))
|
||||
{
|
||||
shorts.Add(s);
|
||||
}
|
||||
}
|
||||
return shorts.ToArray();
|
||||
}
|
||||
private string [] ToStringArray(string line)
|
||||
{
|
||||
return line.Split(new[] { SEPARATOR }, StringSplitOptions.None);
|
||||
}
|
||||
private double [] ToDoubleArray(string line)
|
||||
{
|
||||
var doubles = new List<double>();
|
||||
var tokens = line.Split(new[] { SEPARATOR }, StringSplitOptions.None);
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (double.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out double d))
|
||||
{
|
||||
doubles.Add(d);
|
||||
}
|
||||
}
|
||||
return doubles.ToArray();
|
||||
}
|
||||
private const string SEPARATOR = ",";
|
||||
public void WriteToFile(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lines = new List<string>();
|
||||
var keys = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case Fields.SerialNumber:
|
||||
lines.Add(SerialNumber);
|
||||
break;
|
||||
case Fields.TiltSensorCals:
|
||||
lines.Add(ToString(TiltSensorCals));
|
||||
break;
|
||||
case Fields.TiltSensorDataPre:
|
||||
lines.Add(ToString(TiltSensorDataPre));
|
||||
break;
|
||||
case Fields.TiltAxes:
|
||||
lines.Add(TiltAxes.ToString());
|
||||
break;
|
||||
case Fields.AxesIgnored:
|
||||
lines.Add(AxisIgnored.ToString());
|
||||
break;
|
||||
case Fields.MountOffsetAxisOne:
|
||||
lines.Add(MountOffsetAxisOne.ToString(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case Fields.MountOffsetAxisTwo:
|
||||
lines.Add(MountOffsetAxisTwo.ToString(CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case Fields.ChannelNames:
|
||||
lines.Add(ToString(_channelNames));
|
||||
break;
|
||||
case Fields.OffsetTolerancesLow:
|
||||
lines.Add(ToString(_offsetTolerancesLow));
|
||||
break;
|
||||
case Fields.OffsetTolerancesHigh:
|
||||
lines.Add(ToString(_offsetTolerancesHigh));
|
||||
break;
|
||||
}
|
||||
}
|
||||
File.WriteAllLines(path, lines.ToArray());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
private string ToString(string[] values)
|
||||
{
|
||||
return string.Join(SEPARATOR, values);
|
||||
}
|
||||
private string ToString(double[] values)
|
||||
{
|
||||
var l = new List<string>();
|
||||
foreach (var val in values)
|
||||
{
|
||||
l.Add(val.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
return ToString(l.ToArray());
|
||||
}
|
||||
private string ToString(short[] values)
|
||||
{
|
||||
var l = new List<string>();
|
||||
foreach (var val in values)
|
||||
{
|
||||
l.Add(val.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
return ToString(l.ToArray());
|
||||
}
|
||||
private enum Fields
|
||||
{
|
||||
SerialNumber,
|
||||
TiltSensorCals,
|
||||
TiltSensorDataPre,
|
||||
TiltAxes,
|
||||
AxesIgnored,
|
||||
MountOffsetAxisOne,
|
||||
MountOffsetAxisTwo,
|
||||
ChannelNames,
|
||||
OffsetTolerancesLow,
|
||||
OffsetTolerancesHigh
|
||||
}
|
||||
private double [] GetTiltSensorCals(IDASCommunication das)
|
||||
{
|
||||
return das is ITiltSensorCalAware iTiltAware ? iTiltAware.TiltSensorCals : (new double[0]);
|
||||
}
|
||||
private short [] GetTiltSensorData(IDASCommunication das)
|
||||
{
|
||||
return new short[] { 0, 0, 0 };
|
||||
}
|
||||
public DASMonitorInfo(IDASCommunication das, IsoViewMode mode)
|
||||
{
|
||||
var keys = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case Fields.SerialNumber:
|
||||
SerialNumber = das.SerialNumber;
|
||||
break;
|
||||
case Fields.TiltSensorCals:
|
||||
TiltSensorCals = GetTiltSensorCals(das);
|
||||
break;
|
||||
case Fields.TiltSensorDataPre:
|
||||
TiltSensorDataPre = GetTiltSensorData(das);
|
||||
break;
|
||||
case Fields.TiltAxes:
|
||||
TiltAxes = GetTiltAxes(das);
|
||||
break;
|
||||
case Fields.AxesIgnored:
|
||||
AxisIgnored = GetAxisIgnored(das);
|
||||
break;
|
||||
case Fields.MountOffsetAxisOne:
|
||||
MountOffsetAxisOne = GetMountOffsetAxisOne(das);
|
||||
break;
|
||||
case Fields.MountOffsetAxisTwo:
|
||||
MountOffsetAxisTwo = GetMountOffsetAxisTwo(das);
|
||||
break;
|
||||
case Fields.ChannelNames:
|
||||
_channelNames = GetChannelNames(das, mode);
|
||||
break;
|
||||
case Fields.OffsetTolerancesLow:
|
||||
_offsetTolerancesLow = GetOffsetTolerancemVLow(das);
|
||||
break;
|
||||
case Fields.OffsetTolerancesHigh:
|
||||
_offsetTolerancesHigh = GetOffsetTolerancemVHigh(das);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private double [] GetOffsetTolerancemVHigh(IDASCommunication das)
|
||||
{
|
||||
if (NoModules(das)) { return new double[0]; }
|
||||
var list = new List<double>();
|
||||
foreach (var module in das.ConfigData.Modules)
|
||||
{
|
||||
foreach (var ch in module.Channels)
|
||||
{
|
||||
if (ch is IAnalogInputDASChannel aic)
|
||||
{
|
||||
list.Add(aic.OffsetToleranceHighMilliVolts);
|
||||
}
|
||||
else { list.Add(0); }
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
private double [] GetOffsetTolerancemVLow(IDASCommunication das)
|
||||
{
|
||||
if (NoModules(das)) { return new double[0]; }
|
||||
var list = new List<double>();
|
||||
foreach (var module in das.ConfigData.Modules)
|
||||
{
|
||||
foreach (var ch in module.Channels)
|
||||
{
|
||||
if (ch is IAnalogInputDASChannel aic)
|
||||
{
|
||||
list.Add(aic.OffsetToleranceLowMilliVolts);
|
||||
}
|
||||
else { list.Add(0); }
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
private bool NoModules(IDASCommunication das)
|
||||
{
|
||||
return null == das.ConfigData || null == das.ConfigData.Modules || 0 == das.ConfigData.Modules.Length;
|
||||
}
|
||||
private double GetMountOffsetAxisTwo(IDASCommunication das)
|
||||
{
|
||||
return NoModules(das) ? float.NaN : das.ConfigData.Modules[0].MountOffsetAxisTwo;
|
||||
}
|
||||
private double GetMountOffsetAxisOne(IDASCommunication das)
|
||||
{
|
||||
return NoModules(das) ? float.NaN : das.ConfigData.Modules[0].MountOffsetAxisOne;
|
||||
}
|
||||
private int GetAxisIgnored(IDASCommunication das)
|
||||
{
|
||||
return NoModules(das) ? 0 : das.ConfigData.Modules[0].AxisIgnored;
|
||||
}
|
||||
private DFConstantsAndEnums.TiltAxes GetTiltAxes(IDASCommunication das)
|
||||
{
|
||||
return NoModules(das) ? DFConstantsAndEnums.TiltAxes.IXIYIZ : das.ConfigData.Modules[0].TiltAxes;
|
||||
}
|
||||
private string [] GetChannelNames(IDASCommunication das, IsoViewMode viewMode)
|
||||
{
|
||||
if(NoModules(das)) { return new string[0]; }
|
||||
var list = new List<string>();
|
||||
foreach (var mod in das.ConfigData.Modules)
|
||||
{
|
||||
foreach (var ch in mod.Channels)
|
||||
{
|
||||
switch (viewMode)
|
||||
{
|
||||
case IsoViewMode.ISOOnly:
|
||||
list.Add(ch.IsoChannelName);
|
||||
break;
|
||||
case IsoViewMode.ISOAndUserCode:
|
||||
list.Add($"{ ch.IsoChannelName}\\{ch.UserChannelName}");
|
||||
break;
|
||||
case IsoViewMode.UserCodeOnly:
|
||||
list.Add(ch.UserCode);
|
||||
break;
|
||||
case IsoViewMode.ChannelNameOnly:
|
||||
list.Add(ch.UserChannelName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
public DASMonitorInfo(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
ReadFromFile(path);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using Microsoft.Practices.Prism.Events;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Event to inform app that it should mark itself busy or available
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///
|
||||
/// </remarks>
|
||||
public class PageErrorEvent : CompositePresentationEvent<PageErrorArg>
|
||||
{
|
||||
/// <summary>
|
||||
/// surfaces an error to the application, if applicable
|
||||
/// http://manuscript.dts.local/f/cases/28312/Surface-Read-does-not-match-write-to-user
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
public static void SurfaceApplicationError(string msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
var eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
|
||||
eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { msg }, null));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PageErrorArg
|
||||
{
|
||||
public string [] Errors { get; }
|
||||
public object Page { get; }
|
||||
public bool Handled { get; set; }
|
||||
public PageErrorArg(string[] errors, object page)
|
||||
{
|
||||
Errors = errors;
|
||||
Page = page;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Classes.ChannelCodes;
|
||||
using DTS.Common.Classes.Groups;
|
||||
using DTS.Common.Converters;
|
||||
using DTS.Common.Enums.Channels;
|
||||
using DTS.Common.Events;
|
||||
using DTS.Common.Events.Groups.GroupChannelList;
|
||||
using DTS.Common.Interface.Channels.ChannelCodes;
|
||||
using Microsoft.Practices.Prism.Events;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
|
||||
namespace DTS.Common.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ChannelNameBuilder.xaml
|
||||
/// built from ChannelCodeBuilder then simplified a little
|
||||
/// http://manuscript.dts.local/f/cases/17565/
|
||||
/// </summary>
|
||||
public partial class ChannelNameBuilder : UserControl, IBasePropertyChanged
|
||||
{
|
||||
private LookupPopup _lookupPopup;
|
||||
|
||||
private DispatcherTimer _possiblesTimer;
|
||||
|
||||
public ChannelNameBuilder()
|
||||
{
|
||||
InitializeComponent();
|
||||
Loaded += (sender, args) => { if (!_registered) RegisterCommands(); };
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CodeTypeProperty =
|
||||
DependencyProperty.Register(
|
||||
"CodeType", // The name of the DependencyProperty
|
||||
typeof(ChannelEnumsAndConstants.ChannelCodeType), // The type of the DependencyProperty
|
||||
typeof(ChannelNameBuilder), // The type of the owner of the DependencyProperty
|
||||
new PropertyMetadata( // OnHeaderTitleChanged will be called when HeaderTitle changes
|
||||
ChannelEnumsAndConstants.ChannelCodeType.User // The default value of the DependencyProperty
|
||||
)
|
||||
);
|
||||
|
||||
public ChannelEnumsAndConstants.ChannelCodeType CodeType
|
||||
{
|
||||
get => (ChannelEnumsAndConstants.ChannelCodeType) GetValue(CodeTypeProperty);
|
||||
set => SetValue(CodeTypeProperty, value);
|
||||
}
|
||||
|
||||
private static readonly DependencyProperty ChannelNameProperty =
|
||||
DependencyProperty.Register(
|
||||
"ChannelName", // The name of the DependencyProperty
|
||||
typeof(string), // The type of the DependencyProperty
|
||||
typeof(ChannelNameBuilder), // The type of the owner of the DependencyProperty
|
||||
new PropertyMetadata( // OnHeaderTitleChanged will be called when HeaderTitle changes
|
||||
"", // The default value of the DependencyProperty
|
||||
OnChannelNameChanged
|
||||
)
|
||||
);
|
||||
|
||||
private volatile bool _bInSet = false;
|
||||
|
||||
public void SetNameProperty(string value)
|
||||
{
|
||||
if( _bInSet ){ return; }
|
||||
_bInSet = true;
|
||||
SetValue(ChannelNameProperty, value);
|
||||
_bInSet = false;
|
||||
}
|
||||
private static void OnChannelNameChanged(
|
||||
DependencyObject d,
|
||||
DependencyPropertyChangedEventArgs e
|
||||
)
|
||||
{
|
||||
ChannelNameBuilder cnb = (ChannelNameBuilder)d;
|
||||
cnb.SetValue(ChannelNameProperty, e.NewValue);
|
||||
cnb.UpdatePossibleChannels();
|
||||
}
|
||||
|
||||
public string ChannelName
|
||||
{
|
||||
get => (string) GetValue(ChannelNameProperty);
|
||||
set => SetValue(ChannelNameProperty, value);
|
||||
}
|
||||
|
||||
|
||||
public static readonly DependencyProperty ChannelNamesFuncProperty =
|
||||
DependencyProperty.Register(
|
||||
"ChannelNamesFunc",
|
||||
typeof(Func<IList<IChannelCode>>),
|
||||
typeof(ChannelNameBuilder),
|
||||
new PropertyMetadata(null)
|
||||
);
|
||||
|
||||
public Func<IList<IChannelCode>> ChannelNamesFunc
|
||||
{
|
||||
get => (Func<IList<IChannelCode>>) GetValue(ChannelNamesFuncProperty);
|
||||
set => SetValue(ChannelNamesFuncProperty, value);
|
||||
}
|
||||
|
||||
#region ISO builder properties
|
||||
|
||||
private ICommand _pasteCommand;
|
||||
public ICommand PasteCommand
|
||||
{
|
||||
get => _pasteCommand;
|
||||
set { _pasteCommand = value; OnPropertyChanged("PasteCommand"); }
|
||||
}
|
||||
|
||||
private static readonly DependencyProperty PasteIdProperty =
|
||||
DependencyProperty.Register(
|
||||
"PasteId", // The name of the DependencyProperty
|
||||
typeof(string), // The type of the DependencyProperty
|
||||
typeof(ChannelNameBuilder), // The type of the owner of the DependencyProperty
|
||||
new PropertyMetadata( // OnHeaderTitleChanged will be called when HeaderTitle changes
|
||||
GroupChannel.PASTE_ID // The default value of the DependencyProperty
|
||||
)
|
||||
);
|
||||
public string PasteId
|
||||
{
|
||||
get => (string)GetValue(PasteIdProperty);
|
||||
set => SetValue(PasteIdProperty, value);
|
||||
}
|
||||
|
||||
private bool _registered = false;
|
||||
private void RegisterCommands()
|
||||
{
|
||||
// FB13293: In order to add CCB to Channel Codes tile, we have to expand support for paste types
|
||||
switch (PasteId)
|
||||
{
|
||||
case ChannelCode.PASTE_ID:
|
||||
PasteCommand = new Classes.ChannelCodes.PasteCommandClass(PasteId);
|
||||
break;
|
||||
case GroupChannel.PASTE_ID:
|
||||
default:
|
||||
PasteCommand = new Classes.Groups.PasteCommandClass(PasteId);
|
||||
break;
|
||||
}
|
||||
CommandManager.RegisterClassCommandBinding(GetType(),
|
||||
new CommandBinding(PasteCommand, Paste));
|
||||
_registered = true;
|
||||
}
|
||||
private void Paste(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ChannelCode select properties
|
||||
|
||||
public static readonly DependencyProperty AllChannelCodesProperty =
|
||||
DependencyProperty.Register(
|
||||
"AllChannelCodes", // The name of the DependencyProperty
|
||||
typeof(IEnumerable<IChannelCode>), // The type of the DependencyProperty
|
||||
typeof(ChannelNameBuilder), // The type of the owner of the DependencyProperty
|
||||
new PropertyMetadata( // OnHeaderTitleChanged will be called when HeaderTitle changes
|
||||
new List<IChannelCode>(), // The default value of the DependencyProperty
|
||||
OnAllChannelCodesChanged
|
||||
)
|
||||
);
|
||||
|
||||
private static void OnAllChannelCodesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ChannelNameBuilder ccb = (ChannelNameBuilder) d;
|
||||
|
||||
ccb?.UpdatePossibleChannels();
|
||||
}
|
||||
|
||||
public IList<IChannelCode> AllChannelCodes
|
||||
{
|
||||
get => (IList<IChannelCode>)GetValue(AllChannelCodesProperty);
|
||||
set => SetValue(AllChannelCodesProperty, value);
|
||||
}
|
||||
/// <summary>
|
||||
/// lock to enforce updatepossiblechannels doesn't become re-entrant
|
||||
/// </summary>
|
||||
private static object MyLock = new object();
|
||||
/// <summary>
|
||||
/// this is the method that updates the popup with channel codes
|
||||
/// immediate means do it now, (as opposed to whenever the user stops typing)
|
||||
/// this is done by using a timer, as long as the user keeps typing the timer gets reset
|
||||
/// </summary>
|
||||
/// <param name="immediateUpdate"></param>
|
||||
public void UpdatePossibleChannels(bool immediateUpdate = false)
|
||||
{
|
||||
if (null == _lookupPopup) return;
|
||||
lock (MyLock)
|
||||
{
|
||||
var nameUpple = ChannelName.ToUpper();
|
||||
if (immediateUpdate)
|
||||
{
|
||||
_possiblesTimer?.Stop();
|
||||
_possiblesTimer = null;
|
||||
_lookupPopup.PossibleChannels = ChannelNamesFunc?.Invoke()
|
||||
.Where(ch =>
|
||||
ch.CodeType == CodeType &&
|
||||
ch.Name.ToUpper().Contains(nameUpple)).Select(
|
||||
code => new {code.Code, code.Name}).ToList() ??
|
||||
AllChannelCodes
|
||||
.Where(ch =>
|
||||
ch.CodeType == CodeType &&
|
||||
ch.Name.ToUpper().Contains(nameUpple))
|
||||
.Select(code => new {code.Code, code.Name}).ToList() ??
|
||||
Enumerable.Repeat(new {Code = "", Name = ""}, 0).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (null == _possiblesTimer)
|
||||
{
|
||||
_possiblesTimer = new DispatcherTimer()
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(LookupHelperUpdateDelay),
|
||||
IsEnabled = false
|
||||
};
|
||||
_possiblesTimer.Tick += (sender, args) => { UpdatePossibleChannels(true); };
|
||||
_possiblesTimer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
_possiblesTimer.Stop();
|
||||
_possiblesTimer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowChannelCodeLookupHelperProperty =
|
||||
DependencyProperty.Register(
|
||||
"ShowChannelCodeLookupHelper", // The name of the DependencyProperty
|
||||
typeof(bool), // The type of the DependencyProperty
|
||||
typeof(ChannelNameBuilder), // The type of the owner of the DependencyProperty
|
||||
new PropertyMetadata( // OnHeaderTitleChanged will be called when HeaderTitle changes
|
||||
true, // The default value of the DependencyProperty
|
||||
OnShowChannelCodeLookupHelperChanged
|
||||
)
|
||||
);
|
||||
|
||||
private static void OnShowChannelCodeLookupHelperChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ChannelNameBuilder ccb = (ChannelNameBuilder)d;
|
||||
if (!(bool) e.NewValue)
|
||||
{
|
||||
ccb._lookupPopup = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowChannelCodeLookupHelper
|
||||
{
|
||||
get => (bool)GetValue(ShowChannelCodeLookupHelperProperty);
|
||||
set => SetValue(ShowChannelCodeLookupHelperProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LookupHelperUpdateDelay2Property =
|
||||
DependencyProperty.Register(
|
||||
"LookupHelperUpdateDelay2", // The name of the DependencyProperty
|
||||
typeof(int), // The type of the DependencyProperty
|
||||
typeof(ChannelNameBuilder), // The type of the owner of the DependencyProperty
|
||||
new PropertyMetadata(
|
||||
400,
|
||||
LookupHelperUpdateDelay2Changed,
|
||||
CoerceLookupHelperUpdateDelay2
|
||||
)
|
||||
);
|
||||
|
||||
private static object CoerceLookupHelperUpdateDelay2(DependencyObject d, object baseValue)
|
||||
{
|
||||
return (int) baseValue < 0 ? 0 : (int) baseValue;
|
||||
}
|
||||
|
||||
private static void LookupHelperUpdateDelay2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is ChannelNameBuilder ccb)) return;
|
||||
ccb._possiblesTimer?.Stop();
|
||||
ccb._possiblesTimer = null;
|
||||
}
|
||||
|
||||
public int LookupHelperUpdateDelay
|
||||
{
|
||||
get => (int) GetValue(LookupHelperUpdateDelay2Property);
|
||||
set => SetValue(LookupHelperUpdateDelay2Property, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public delegate void ChannelCodeSelectedEventHandler(object sender, string code, string name, ChannelEnumsAndConstants.ChannelCodeType codeType);
|
||||
|
||||
public event ChannelCodeSelectedEventHandler ChannelCodeSelected;
|
||||
|
||||
public void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
private void MainEditBox_OnGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
if (sender.Equals(MainEditBox))
|
||||
{
|
||||
MultiBinding lookupMB = null, isoMB = null;
|
||||
if (ShowChannelCodeLookupHelper && null == _lookupPopup)
|
||||
{
|
||||
_lookupPopup = new LookupPopup()
|
||||
{
|
||||
PlacementTarget = MainEditBox,
|
||||
HorizontalOffset = 10,
|
||||
Placement = PlacementMode.Custom,
|
||||
CustomPopupPlacementCallback = (size, targetSize, offset) =>
|
||||
{
|
||||
CustomPopupPlacement bottom = new CustomPopupPlacement(new Point(0, targetSize.Height), PopupPrimaryAxis.Horizontal);
|
||||
CustomPopupPlacement left = new CustomPopupPlacement(new Point(-size.Width - offset.X, 0), PopupPrimaryAxis.Vertical);
|
||||
var topoffset = 0;
|
||||
CustomPopupPlacement top = new CustomPopupPlacement(new Point(0, -size.Height - topoffset), PopupPrimaryAxis.Horizontal);
|
||||
|
||||
return new CustomPopupPlacement[] { bottom, left, top };
|
||||
},
|
||||
};
|
||||
_lookupPopup.ChannelCodeSelected += LookupPopupOnChannelCodeSelected;
|
||||
lookupMB = new MultiBinding();
|
||||
lookupMB.Converter = new BooleanOrMultiConverter();
|
||||
lookupMB.Bindings.Add(new Binding("IsKeyboardFocused") { Source = MainEditBox, Mode = BindingMode.OneWay });
|
||||
lookupMB.Bindings.Add(new Binding("IsKeyboardFocusWithin") { Source = _lookupPopup, Mode = BindingMode.OneWay });
|
||||
lookupMB.NotifyOnSourceUpdated = true;
|
||||
}
|
||||
|
||||
if (null != lookupMB)
|
||||
{
|
||||
_lookupPopup.SetBinding(Popup.IsOpenProperty, lookupMB);
|
||||
}
|
||||
if (null != _lookupPopup)
|
||||
{
|
||||
UpdatePossibleChannels(true);
|
||||
}
|
||||
if (null != isoMB)
|
||||
{
|
||||
if (null != _lookupPopup)
|
||||
{
|
||||
isoMB.Bindings.Add(new Binding("IsKeyboardFocusWithin") { Source = _lookupPopup, Mode = BindingMode.OneWay });
|
||||
}
|
||||
}
|
||||
}
|
||||
if(sender is TextBox tb)
|
||||
{
|
||||
tb.SelectAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void LookupPopupOnChannelCodeSelected(object sender, string code, string name)
|
||||
{
|
||||
ChannelName = name;
|
||||
ChannelCodeSelected?.Invoke(this, code, name, CodeType);
|
||||
Keyboard.ClearFocus();
|
||||
}
|
||||
|
||||
private void MainEditBox_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (CodeType != ChannelEnumsAndConstants.ChannelCodeType.ISO) { return; }
|
||||
//might be faster to have a preset regex for this, but seems to run really fast anyhow...
|
||||
bool isAlpha = (e.Key >= Key.A && e.Key <= Key.Z) || e.Key == Key.Space; //need to allow space for names.
|
||||
bool isNumPadNumeric = (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9);
|
||||
bool isNumeric = (e.Key >= Key.D0 && e.Key <= Key.D9);
|
||||
bool isControl = e.Key == Key.Enter || e.Key == Key.Return || e.Key == Key.Tab || e.Key == Key.OemBackTab ||
|
||||
e.Key == Key.Delete || e.Key == Key.Back || e.Key == Key.Home || e.Key == Key.End;
|
||||
bool isDirection = e.Key == Key.Up || e.Key == Key.Down || e.Key == Key.Left || e.Key == Key.Right;
|
||||
e.Handled = !(e.Key == Key.OemQuestion || isAlpha || isNumPadNumeric || isNumeric || isControl || isDirection);
|
||||
}
|
||||
|
||||
private void MainEditBox_OnLostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!IsKeyboardFocusWithin && (!_lookupPopup?.IsKeyboardFocusWithin ?? true))
|
||||
{
|
||||
//now that we've lost focus, we can coerce the code
|
||||
//Code = Code;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChannelNameBuilder_OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Window w = Window.GetWindow(this);
|
||||
if (w != null)
|
||||
{
|
||||
w.LocationChanged += delegate
|
||||
{
|
||||
if (IsKeyboardFocusWithin )
|
||||
{
|
||||
Keyboard.ClearFocus();
|
||||
}
|
||||
};
|
||||
}
|
||||
var scrollParent = Utils.Utils.FindParent<ScrollViewer>(this);
|
||||
if (scrollParent != null)
|
||||
{
|
||||
scrollParent.ScrollChanged += delegate(object o, ScrollChangedEventArgs args)
|
||||
{
|
||||
if (IsKeyboardFocusWithin &&
|
||||
(args.HorizontalChange != 0 || args.VerticalChange != 0))
|
||||
{
|
||||
Keyboard.ClearFocus();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void TextBoxSourceUpdated(object sender, DataTransferEventArgs e)
|
||||
{
|
||||
var eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
|
||||
eventAggregator.GetEvent<PageModifiedEvent>()
|
||||
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, null));
|
||||
eventAggregator.GetEvent<GroupUpdatedEvent>()
|
||||
.Publish(new GroupUpdatedEventArgs(null, GroupUpdatedEventArgs.Status.AssignmentsMade));
|
||||
}
|
||||
|
||||
private void MainEditBox_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is TextBox tb)
|
||||
{
|
||||
tb.SelectAll();
|
||||
}
|
||||
}
|
||||
|
||||
public event TextChangedEventHandler TextChanged;
|
||||
private void MainEditBox_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
TextChanged?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using DTS.Common.Base;
|
||||
|
||||
namespace DTS.Common.Interface.DASFactory.Diagnostics.HardwareList
|
||||
{
|
||||
public interface IHardwareListOverdueView : IBaseView { }
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
Reference in New Issue
Block a user