This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
using DTS.Common.Base;
namespace DTS.Common.Interface
{
public interface ITestSettingsViewModel : IBaseViewModel { }
}

View File

@@ -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>

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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