init
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 538 B |
@@ -0,0 +1,39 @@
|
||||
<UserControl x:Class="DTS.Common.Controls.ChannelCodeBuilder"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:DTS.Common.Controls"
|
||||
xmlns:strings="clr-namespace:DTS.Common.Strings"
|
||||
xmlns:behaviors="clr-namespace:DTS.Common.Behaviors"
|
||||
mc:Ignorable="d"
|
||||
x:Name="dtsChannelCodeBuilder"
|
||||
d:DesignHeight="450" d:DesignWidth="800" Loaded="ChannelCodeBuilder_OnLoaded"
|
||||
AutomationProperties.AutomationId="CodeChannelBuilderUserControl"
|
||||
>
|
||||
<UserControl.Resources>
|
||||
<local:CodeTypeToMaxLengthConverter x:Key="CodeTypeToMaxLengthConverter" />
|
||||
<local:CodeTypeToCharacterCasingConverter x:Key="CodeTypeToCharacterCasingConverter" />
|
||||
</UserControl.Resources>
|
||||
<TextBox x:Name="MainEditBox" FontFamily="Courier New" x:FieldModifier="public" HorizontalAlignment="Stretch" DataContext="{Binding ElementName=dtsChannelCodeBuilder}"
|
||||
MaxLength="{Binding CodeType, Converter={StaticResource CodeTypeToMaxLengthConverter}}"
|
||||
LostFocus="MainEditBox_OnLostFocus"
|
||||
GotKeyboardFocus="MainEditBox_OnGotKeyboardFocus"
|
||||
MouseDoubleClick="MainEditBox_OnMouseDoubleClick"
|
||||
PreviewKeyDown="MainEditBox_OnPreviewKeyDown"
|
||||
AutomationProperties.AutomationId="CCB_MainEditTextBox"
|
||||
behaviors:TextBoxPasteBehavior.PasteCommand="{Binding PasteCommand}"
|
||||
Binding.SourceUpdated="TextBoxSourceUpdated" CharacterCasing="{Binding ElementName=dtsChannelCodeBuilder,Path=CodeType, Converter={StaticResource CodeTypeToCharacterCasingConverter}}"
|
||||
TextChanged="MainEditBox_OnTextChanged"
|
||||
SelectionChanged="MainEditBox_SelectionChanged"
|
||||
Tag="{Binding Tag}">
|
||||
<TextBox.Text>
|
||||
<Binding NotifyOnSourceUpdated="True" Path="Code" UpdateSourceTrigger="PropertyChanged" />
|
||||
</TextBox.Text>
|
||||
<TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter"
|
||||
Command="{local:UpdatePropertySourceWhenEnterPressed}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}" />
|
||||
</TextBox.InputBindings>
|
||||
</TextBox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,25 @@
|
||||
using DTS.Common.Converters;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace DTS.Common.Enums.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// the format Initial Offset is in
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(EnumDescriptionTypeConverter))]
|
||||
public enum InitialOffsetTypes
|
||||
{
|
||||
[Description("InitialOffsetType_None")]
|
||||
None = 0,
|
||||
[Description("InitialOffsetType_EU")]
|
||||
EU = 1,
|
||||
[Description("InitialOffsetType_EUAtMV")]
|
||||
EUAtMV = 2,
|
||||
[Description("InitialOffsetType_LHS")]
|
||||
LHS = 3,
|
||||
[Description("InitialOffsetType_RHS")]
|
||||
RHS = 4,
|
||||
[Description("InitialOffsetType_FRONTAL")]
|
||||
FRONTAL = 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Events.TSRAIRGo
|
||||
{
|
||||
|
||||
public class DASSampleRateChangedEvent : PubSubEvent<DASSampleRateArg> { }
|
||||
public class DASListChangedEvent : PubSubEvent<bool> { }
|
||||
|
||||
public class DASSampleRateArg
|
||||
{
|
||||
public int SampleRate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using DTS.Common.Interface.TestSetups.Imports.TTS.ReadFile;
|
||||
using DTS.Common.Interface.TestSetups.TestSetupsList;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Events
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The TTSImportReadXMLFileEvent event.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>This event is used by the Read File step to tell the page to read an xml file.</remarks>
|
||||
public class TTSImportReadXMLFileRequestEvent : PubSubEvent<TTSImportReadXMLFileRequestArg> { }
|
||||
|
||||
public class TTSImportReadXMLFileRequestArg
|
||||
{
|
||||
public ITTSSetup TestSetup { get; private set; }
|
||||
public string FilePath { get; private set; }
|
||||
|
||||
public TTSImportReadXMLFileRequestArg(string filePath, ITTSSetup setup)
|
||||
{
|
||||
FilePath = filePath;
|
||||
TestSetup = setup;
|
||||
}
|
||||
}
|
||||
|
||||
public class TTSImportReadXMLFileResponseEvent : PubSubEvent<TTSImportReadXMLFileResponseEventArg>
|
||||
{
|
||||
}
|
||||
|
||||
public class TTSImportReadXMLLevelTrigger
|
||||
{
|
||||
public double Threshold { get; private set; }
|
||||
public string SensorSerialNumber { get; private set; }
|
||||
|
||||
public TTSImportReadXMLLevelTrigger(double threshold, string sensorSerialNumber)
|
||||
{
|
||||
Threshold = threshold;
|
||||
SensorSerialNumber = sensorSerialNumber;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// this event is a response to a read file request
|
||||
/// </summary>
|
||||
public class TTSImportReadXMLFileResponseEventArg
|
||||
{
|
||||
public ITestSetup TestSetup { get; private set; }
|
||||
public string[] Errors { get; private set; }
|
||||
public ITTSSetup TTSSetup { get; private set; }
|
||||
public TTSImportReadXMLLevelTrigger[] LevelTriggers { get; private set; }
|
||||
public TTSImportReadXMLFileResponseEventArg(ITestSetup setup, string[] errors, ITTSSetup ttsSetup,
|
||||
TTSImportReadXMLLevelTrigger[] levelTriggers)
|
||||
{
|
||||
TestSetup = setup;
|
||||
Errors = errors;
|
||||
TTSSetup = ttsSetup;
|
||||
LevelTriggers = levelTriggers;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using DTS.Common.Interface.Channels;
|
||||
namespace DTS.Common.Classes.Groups.ChannelSettings
|
||||
{
|
||||
public class ChannelSettingBase : IChannelSetting
|
||||
{
|
||||
//analog parameters
|
||||
public const string RANGE = "Range";
|
||||
public const string CFC = "CFC";
|
||||
//FB 13120 Add FilterClass
|
||||
public const string FilterClass = "FilterClass";
|
||||
public const string POLARITY = "Polarity";
|
||||
public const string POSITION = "Position";
|
||||
public const string ZEROMETHOD = "ZeroMethod";
|
||||
public const string ZEROMETHODSTART = "ZeroMethodStart";
|
||||
public const string ZEROMETHODEND = "ZeroMethodEnd";
|
||||
public const string USERVALUE1 = "UserValue1";
|
||||
public const string USERVALUE2 = "UserValue2";
|
||||
public const string USERVALUE3 = "UserValue3";
|
||||
public const string INITIAL_OFFSET = "InitialOffset";
|
||||
|
||||
/// <summary>
|
||||
/// the string key for the ac coupled enabled channel setting
|
||||
/// http://manuscript.dts.local/f/cases/29760/Implement-ACCoupleEnable-for-TSR-AIR
|
||||
/// </summary>
|
||||
public const string ACCouplingEnabled = "ACCouplingEnabled";
|
||||
//depreciated parameters
|
||||
//public const string LIMIT_DURATION = "LimitDuration";
|
||||
//public const string DURATION = "Duration";
|
||||
//public const string DELAY = "Delay";
|
||||
//33415 Voltage insertion channel should be half bridge
|
||||
public const string BRIDGE_TYPE = "BridgeType";
|
||||
|
||||
//squib parameters
|
||||
public const string SQUIB_CURRENT = "SquibCurrent";
|
||||
public const string SQUIB_LIMIT_DURATION = "SquibLimitDuration";
|
||||
public const string SQUIB_DURATION = "SquibDuration";
|
||||
public const string SQUIB_DELAY = "SquibDelay";
|
||||
public const string SQMODE = "SQMode";
|
||||
|
||||
//digital out parameters
|
||||
public const string DIGITALOUT_LIMIT_DURATION = "DigitalOutLimitDuration";
|
||||
public const string DIGITALOUT_DURATION = "DigitalOutDuration";
|
||||
public const string DIGITALOUT_DELAY = "DigitalOutDelay";
|
||||
public const string OUTPUT_MODE = "OutputMode";
|
||||
|
||||
//digital in parameters
|
||||
public const string DIMODE = "DIMode";
|
||||
public const string DEFAULT_VALUE = "DefaultValue";
|
||||
public const string ACTIVE_VALUE = "ActiveValue";
|
||||
|
||||
//uart parameters 18363
|
||||
public const string BAUD_RATE = "UartBaudRate";
|
||||
public const string DATA_BITS = "UartDataBits";
|
||||
public const string STOP_BITS = "UartStopBits";
|
||||
public const string PARITY = "UartParity";
|
||||
public const string FLOW_CONTROL = "UartFlowControl";
|
||||
public const string DATA_FORMAT = "UartDataFormat";
|
||||
//streamout parameters 18363
|
||||
public const string UDP_PROFILE = "StreamOutUDPProfile";
|
||||
public const string UDP_ADDRESS = "StreamOutUDPAddress";
|
||||
public const string UDP_TIME_CHID = "StreamOutUDPTimeChannelId";
|
||||
public const string UDP_DATA_CHID = "StreamOutUDPDataChannelId";
|
||||
public const string UDP_TMNS_CONFIG = "StreamOutUDPTmNSConfig";
|
||||
public const string IRIG_TDP_INTERVAL_MS = "StreamOutIRIGTimeDataPacketIntervalMs";
|
||||
public const string TMATS_INTERVAL_MS = "StreamOutTMATSIntervalMs";
|
||||
//streamin parameters 26828
|
||||
public const string UDP_ADDRESS_IN = "StreamInUDPAddress";
|
||||
|
||||
public ChannelSettingBase(int settingType, string name, string defaultValue)
|
||||
{
|
||||
SettingTypeId = settingType;
|
||||
SettingName = name;
|
||||
DefaultValue = defaultValue;
|
||||
}
|
||||
public IChannelSetting Clone()
|
||||
{
|
||||
return new ChannelSettingBase(this);
|
||||
}
|
||||
private ChannelSettingBase(IChannelSetting setting)
|
||||
{
|
||||
ChannelId = setting.ChannelId;
|
||||
SettingTypeId = setting.SettingTypeId;
|
||||
SettingName = setting.SettingName;
|
||||
DefaultValue = setting.DefaultValue;
|
||||
Value = setting.Value;
|
||||
}
|
||||
public long ChannelId { get; set; }
|
||||
public int SettingTypeId { get; protected set; }
|
||||
public string SettingName { get; protected set; }
|
||||
public string DefaultValue { get; protected set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
public double DoubleValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (double.TryParse(Value, System.Globalization.NumberStyles.Any,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out double d))
|
||||
{
|
||||
return d;
|
||||
}
|
||||
return DoubleDefaultValue;
|
||||
}
|
||||
set => Value = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public double DoubleDefaultValue => double.Parse(DefaultValue, System.Globalization.NumberStyles.Any,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
public int IntValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (int.TryParse(Value, System.Globalization.NumberStyles.Any,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out int d))
|
||||
{
|
||||
return d;
|
||||
}
|
||||
return IntDefaultValue;
|
||||
}
|
||||
set => Value = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
public int IntDefaultValue => int.Parse(DefaultValue, System.Globalization.NumberStyles.Any,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
public bool BoolValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (bool.TryParse(Value, out bool b))
|
||||
{
|
||||
return b;
|
||||
}
|
||||
return BoolDefaultValue;
|
||||
}
|
||||
set => Value = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public bool BoolDefaultValue => bool.Parse(DefaultValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// ReSharper disable CheckNamespace
|
||||
namespace DTS.Common.Base
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class used to create Model objects
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">Type of the Model object.</typeparam>
|
||||
public abstract class BaseModel<TModel> : BasePropertyChanged, IBaseModel
|
||||
where TModel : class
|
||||
{
|
||||
//DependencyObject,
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Model object.
|
||||
/// </summary>
|
||||
public TModel Model { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create new instance of base class.
|
||||
/// </summary>
|
||||
// ReSharper disable PublicConstructorInAbstractClass
|
||||
// ReSharper disable once EmptyConstructor
|
||||
public BaseModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public bool IsSaved { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -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 Prism.Events;
|
||||
using Prism.Ioc;
|
||||
|
||||
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 = ContainerLocator.Container.Resolve<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,27 @@
|
||||
using DTS.Common.Enums.Channels;
|
||||
using Prism.Events;
|
||||
|
||||
namespace DTS.Common.Events.ChannelCodes
|
||||
{
|
||||
public class ChannelCodeCommittedEvent : PubSubEvent<ChannelCodeCommittedEventArgs[]> { }
|
||||
|
||||
public class ChannelCodeCommittedEventArgs
|
||||
{
|
||||
public ChannelEnumsAndConstants.ChannelCodeType ChannelCodeType { get; private set; }
|
||||
public string Code { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
// indicates whether the user submitting the event has write privilege
|
||||
// for channel codes
|
||||
public bool CanUserCommitChannelCodes { get; private set; }
|
||||
public ChannelCodeCommittedEventArgs(ChannelEnumsAndConstants.ChannelCodeType channelCodeType,
|
||||
string code,
|
||||
string name,
|
||||
bool canUserCommitChannelCodes)
|
||||
{
|
||||
ChannelCodeType = channelCodeType;
|
||||
Code = code;
|
||||
Name = name;
|
||||
CanUserCommitChannelCodes = canUserCommitChannelCodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user