From 9df183996108d2dbf6aec1910f17512c2c77e8e6 Mon Sep 17 00:00:00 2001 From: Philip-S-Martin Date: Fri, 19 Feb 2021 10:23:47 -0600 Subject: [PATCH] Persistence, 2021.1 Camera, Microphone, Driver, Interpreter, and Experiment Selection Tab all are persistent now using the C# configuration manager. 2021.1 is feature complete! --- InstallForge/2021_1_InstallProject.ifp | Bin 0 -> 6830 bytes McIntyreAFC/McIntyreAFC.csproj | 37 ++++---- .../Protocol/Driver/DriverMeta.cs | 5 +- .../Protocol/ExtensionManager.cs | 4 +- ProtocolMasterCore/Protocol/IExtensionMeta.cs | 4 + .../Helpers/NotNullToBoolConverter.cs | 2 +- ProtocolMasterWPF/Model/Camera.cs | 36 +++++-- ProtocolMasterWPF/Model/CameraContainer.cs | 88 ++++++++++++------ .../Model/ExtensionMetaSetting.cs | 27 ++++++ ProtocolMasterWPF/Model/MediaDevices.cs | 60 ++++++++++++ ProtocolMasterWPF/Model/Session.cs | 70 +++++++++++++- .../Properties/Settings.Designer.cs | 52 ++++++++++- .../Properties/Settings.settings | 14 ++- ProtocolMasterWPF/ProtocolMasterWPF.csproj | 4 + ProtocolMasterWPF/Settings.cs | 28 ++++++ .../View/ProtocolSelectView.xaml | 4 +- .../View/ProtocolSelectView.xaml.cs | 26 +++++- .../View/SessionControlBarView.xaml | 6 +- 18 files changed, 391 insertions(+), 76 deletions(-) create mode 100644 InstallForge/2021_1_InstallProject.ifp create mode 100644 ProtocolMasterWPF/Model/ExtensionMetaSetting.cs create mode 100644 ProtocolMasterWPF/Model/MediaDevices.cs create mode 100644 ProtocolMasterWPF/Settings.cs diff --git a/InstallForge/2021_1_InstallProject.ifp b/InstallForge/2021_1_InstallProject.ifp new file mode 100644 index 0000000000000000000000000000000000000000..2d5a8835eed24a02469592eb08d0761e82ec8316 GIT binary patch literal 6830 zcmcgx>u%e~74B~VdWS*!rwgczF1{pb8i1Cln7g`xr0oP|5m4kvnl;H`IYZm(VxO!( z`bd3+erHH2RuW(XG;&~2oZC6yxy<3rm;e6zKke4-C65wb{-fPml=4>|>#<1rH7}Kr zIr}^7Sv|~o&vRZzX+3FOMj6YajAIyUw2WoSrjgRTG(yby{a!-9+c!dPM4re8#roZD z7c0B%)~@Hn;;`-W63c1g;BeqtC>{MU-#%mTyEViYY|!r4pK)vC+CvZ(hDE8mDB&Cstu*W>(I1yXBAVMuB+& z1d@v`YZCo7i$wme-KvB2Rky#94{Q=Gd0IRtpoR)Ex`)4sdix>9^tDJ`>+P(>PT-Pq(K6n(4v zZDY>@mJr_CiHLa~b0BQqSR$fSuJ>-ph1y`$k4nuDFq5~dXYJl6{AfC*75bzEukzn!M?LC3Z9-M~H&O|CtO0WIex znNU#3_993$d@`%DW$jz+u67G>?lACY`uEqbo+Jw{RU1DpInRN{ZPIM`CWPNh6`Gt4 z=Q$sh;+}^iuI{uf!kxLzcE=X&_d;7Ku2ndZYiS<-KdY$ZC$G9zk+0!lS>=>{?N%U6 z&FI5F2W|3b7H>*!llSVkEc9RJVeopWyzzW z7+Af~d5n2Fige_ekB$W#(0Y1qow8pp+AY)k(K_EtxlXxd7eZMmW1B|lN%t95BH#5& zmKl9!P?%JW;hBsc!vD3x^Jmg%;&}f0c^qsilyyI7;yO5DT&J{?QG-zq#X29#RF+LB z`>#)rnZt*QgALD+LpQ~$39I#rO^>yGrXnt-k}GWmQl@u8TR1Zf`qq_eeTcI3QYvjt zqa1}NsnPV0>xu7x^C0ppL0#!JA!*t_y0CnYXC5;uaDxH6*lL^$O!FCVATyrE$Lz=c zQLF5XKWKbYDNlY@GOttN?EKt1IbIc*KW-PP)U~eD!TIqu?YG>KzgdT;na>5h-#=!R zIn+vr*@PF$`W5kPw_f+GfpKu%{LxAL4c+E!Fz7z7#pd|lJ3ni*n&$CsEvsDPaEw#w zO041a`^M?L^OL4>JeSuGk{4FGhu5IOb(Rf4nbGi%2UiuPoa1Fx-TO2j4wf^ET*1;~l!fO$4JCV=J& z4<6yAO?N<<)|B9nu6)j;<~d!Q6*!tB>uM_5H#F_Yp-&flEr|Z;^}D$G{uY*c)dMS_ zgn7ipy4OGLhY4S;y7WwO!|rtlgWtlH%(Y&ocz)~8aD<>$N@P4u#d7mp@G=vIYhXgL z4KMj}%RpA;C=MOA0)NBgijnp;?=USHQIrKJ9I$0_slggz2eAlrR?(&UQoWL4XXYGy^w+ z@)c9z=wK2tfP`T;oQh27S_3UNPEdrrQm}w{5U`-<7GNX|Q za_S-ED@hz4nTGFnVm=t^&C}Qgm=rDLJvUa>(axm?XybSj3InH(Z!@Ge;APp8H?9K$ zIGVb4hQZEi3HBD{2~jBU#iR}OrNPz#l1qpA^Ko!vdk%Abw(#cH?#LOj7q*Y~iw?VS zgUk60;tK=yPYo$<@f6y=NC#H=74+ z;!fQFLW4OAps*3;I#@SmQ^y-#Lb83~PTb&QhmGA}Ml#0`YO{sy1@7=_VtZ_H8I2QALjnFSWKqK`S(XfXfMo=l7?`wHkigKs!reDvJ+mjSz+Peu+pFB~AV zFD6c{3Puelwma>xkv+BF6FQI00oXIs8gw_8j_HCv8-K&VozKXO;d~Z&Xm((w7wnhb zxW3b2w&(ifkg+$1cycFJkk4kcZsycd$khh*J|dVx4!eTUdn_ZzoksLtA#n{mefXa?-^FRSTkRHzMPH*vfz+=4 dPdT^lc=4$LUZ4GHsD@xsyAhntGHh-d`X5#!AGH7g literal 0 HcmV?d00001 diff --git a/McIntyreAFC/McIntyreAFC.csproj b/McIntyreAFC/McIntyreAFC.csproj index c579dd6..fe614c3 100644 --- a/McIntyreAFC/McIntyreAFC.csproj +++ b/McIntyreAFC/McIntyreAFC.csproj @@ -1,23 +1,28 @@  - - netcoreapp3.1 - + + netcoreapp3.1 + - - ..\ProtocolMasterWPF\bin\Debug\netcoreapp3.1\Extensions\ - false - 5 - + + ..\ProtocolMasterWPF\bin\Debug\netcoreapp3.1\Extensions\ + false + 5 + - - - + + ..\ProtocolMasterWPF\bin\Release\netcoreapp3.1\Extensions\ + false + - - - false - - + + + + + + + false + + diff --git a/ProtocolMasterCore/Protocol/Driver/DriverMeta.cs b/ProtocolMasterCore/Protocol/Driver/DriverMeta.cs index 9789f38..7f5c356 100644 --- a/ProtocolMasterCore/Protocol/Driver/DriverMeta.cs +++ b/ProtocolMasterCore/Protocol/Driver/DriverMeta.cs @@ -19,6 +19,9 @@ public DriverMeta(string name, string version, params string[] eventNames) : bas this.Version = version; this.HandlerLabels = eventNames; } + public DriverMeta() + { + } public DriverMeta(IDictionary inputs) { @@ -34,7 +37,7 @@ public override string ToString() public bool Equals([AllowNull] IExtensionMeta other) { - return this.Name == other.Name && this.Version == other.Version; + return this.Name == other.Name && this.Version == other.Version; } } } diff --git a/ProtocolMasterCore/Protocol/ExtensionManager.cs b/ProtocolMasterCore/Protocol/ExtensionManager.cs index 5110ac1..b7f498d 100644 --- a/ProtocolMasterCore/Protocol/ExtensionManager.cs +++ b/ProtocolMasterCore/Protocol/ExtensionManager.cs @@ -50,13 +50,13 @@ public IExtensionMeta Selected { foreach (ExportFactory i in Extensions) { - if ((IExtensionMeta)i.Metadata == value) + if (i.Metadata.Equals(value)) { extensionFactory = i; return; } } - throw new Exception($"No extension of type {typeof(E)} of with metadata {value} is loaded"); + throw new ArgumentException($"No extension of type {typeof(E)} of with metadata {value} is loaded"); } } public IEnumerable Options diff --git a/ProtocolMasterCore/Protocol/IExtensionMeta.cs b/ProtocolMasterCore/Protocol/IExtensionMeta.cs index 1b7c824..7bd48c6 100644 --- a/ProtocolMasterCore/Protocol/IExtensionMeta.cs +++ b/ProtocolMasterCore/Protocol/IExtensionMeta.cs @@ -1,4 +1,7 @@ using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Xml.Serialization; namespace ProtocolMasterCore.Protocol { @@ -7,4 +10,5 @@ public interface IExtensionMeta : IEquatable string Name { get; } string Version { get; } } + } diff --git a/ProtocolMasterWPF/Helpers/NotNullToBoolConverter.cs b/ProtocolMasterWPF/Helpers/NotNullToBoolConverter.cs index 2708dcd..0766dc8 100644 --- a/ProtocolMasterWPF/Helpers/NotNullToBoolConverter.cs +++ b/ProtocolMasterWPF/Helpers/NotNullToBoolConverter.cs @@ -13,7 +13,7 @@ public object Convert(object value, Type targetType, object parameter, CultureIn public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - return value != null; + throw new NotSupportedException(); } } } diff --git a/ProtocolMasterWPF/Model/Camera.cs b/ProtocolMasterWPF/Model/Camera.cs index f8341bf..184bd5a 100644 --- a/ProtocolMasterWPF/Model/Camera.cs +++ b/ProtocolMasterWPF/Model/Camera.cs @@ -30,18 +30,38 @@ private async void InitVideoStore() { videoStore = await StorageFolder.GetFolderFromPathAsync(storagePath); } - public async void InitializeCap(DeviceInformation videoDevice, DeviceInformation audioDevice) + public void InitializeCap(DeviceInformation videoDevice, DeviceInformation audioDevice) { - try + if(videoDevice == null) + Log.Error($"Video Device null"); + if (audioDevice == null) { - await MediaCap.InitializeAsync(new MediaCaptureInitializationSettings() { - VideoDeviceId = videoDevice.Id, - AudioDeviceId = audioDevice.Id - }); + try + { + MediaCap.InitializeAsync(new MediaCaptureInitializationSettings() + { + VideoDeviceId = videoDevice.Id + }).AsTask().Wait(); + } + catch (UnauthorizedAccessException ex) + { + Log.Error($"The app was denied access to the camera: {ex}"); + } } - catch (UnauthorizedAccessException ex) + else { - Log.Error($"The app was denied access to the camera:\t{ex}"); + try + { + MediaCap.InitializeAsync(new MediaCaptureInitializationSettings() + { + VideoDeviceId = videoDevice.Id, + AudioDeviceId = audioDevice.Id + }).AsTask().Wait(); + } + catch (UnauthorizedAccessException ex) + { + Log.Error($"The app was denied access to the camera: {ex}"); + } } } public async void StartPreview() diff --git a/ProtocolMasterWPF/Model/CameraContainer.cs b/ProtocolMasterWPF/Model/CameraContainer.cs index e69229b..a51e9c5 100644 --- a/ProtocolMasterWPF/Model/CameraContainer.cs +++ b/ProtocolMasterWPF/Model/CameraContainer.cs @@ -1,4 +1,6 @@ -using System; +using ProtocolMasterCore.Utility; +using ProtocolMasterWPF.Properties; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -11,53 +13,79 @@ internal class CameraContainer : Observable { public CameraContainer() { - RefreshDevices(); - _videoDevice = VideoDevices.First(); - _audioDevice = AudioDevices.First(); + InitDefaultDevices(); ResetCam(); } - public Camera Cam { get => _cam; private set { _cam = value; NotifyProperty(); } } - private Camera _cam; - public DeviceInformation VideoDevice { get => _videoDevice; set { _videoDevice = value; NotifyProperty(); ResetCam(); } } - private DeviceInformation _videoDevice; - public DeviceInformation AudioDevice { get => _audioDevice; set { _audioDevice = value; NotifyProperty(); ResetCam(); } } - private DeviceInformation _audioDevice; - public void StartRecord() => Cam.StartRecord(); - public void StopRecord() => Cam.StopRecord(); - private DeviceInformationCollection _videoDevices; - public DeviceInformationCollection VideoDevices + public Camera Cam { - get => _videoDevices; - set + get => _cam; + private set { - _videoDevices = value; + _cam = value; NotifyProperty(); } } - public void RefreshDevices() + private Camera _cam; + public DeviceInformation VideoDevice { - Task task = DeviceInformation.FindAllAsync(DeviceClass.VideoCapture).AsTask(); - task.Wait(); - VideoDevices = task.Result; - task.Dispose(); - - task = DeviceInformation.FindAllAsync(DeviceClass.AudioCapture).AsTask(); - task.Wait(); - AudioDevices = task.Result; + get => _videoDevice; + set + { + _videoDevice = value; + NotifyProperty(); + ResetCam(); + if (value.Id != Settings.Default.CameraID) + { + Settings.Default.CameraID = value.Id; + Settings.Default.Save(); + } + } } - private DeviceInformationCollection _audioDevices; - public DeviceInformationCollection AudioDevices + private DeviceInformation _videoDevice; + public DeviceInformation AudioDevice { - get => _audioDevices; + get => _audioDevice; set { - _audioDevices = value; + _audioDevice = value; NotifyProperty(); + ResetCam(); + if(value.Id != Settings.Default.MicrophoneID) + { + Settings.Default.MicrophoneID = value.Id; + Settings.Default.Save(); + } } } + private DeviceInformation _audioDevice; + public void StartRecord() => Cam.StartRecord(); + public void StopRecord() => Cam.StopRecord(); + private void ResetCam() { Cam = new Camera(VideoDevice, AudioDevice); } + + public void InitDefaultDevices() + { + try + { + _videoDevice = MediaDevices.Instance.VideoDeviceByID(Settings.Default.CameraID); + } + catch (Exception e) + { + Log.Error($"Default Camera could not be seleted, exception: {e}"); + VideoDevice = MediaDevices.Instance.VideoDevices.First(); + } + try + { + _audioDevice = MediaDevices.Instance.AudioDeviceByID(Settings.Default.MicrophoneID); + } + catch (Exception e) + { + Log.Error($"Default Microphone could not be seleted, exception: {e}"); + AudioDevice = MediaDevices.Instance.AudioDevices.First(); + } + } } } diff --git a/ProtocolMasterWPF/Model/ExtensionMetaSetting.cs b/ProtocolMasterWPF/Model/ExtensionMetaSetting.cs new file mode 100644 index 0000000..1d6318d --- /dev/null +++ b/ProtocolMasterWPF/Model/ExtensionMetaSetting.cs @@ -0,0 +1,27 @@ +using ProtocolMasterCore.Protocol; +using ProtocolMasterCore.Protocol.Driver; +using ProtocolMasterCore.Protocol.Interpreter; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Diagnostics.CodeAnalysis; +using System.Text; + +namespace ProtocolMasterWPF.Model +{ + [Serializable] + public sealed class ExtensionMetaSetting : IExtensionMeta + { + public string Name { get; set; } + public string Version { get; set; } + public ExtensionMetaSetting() { } + public ExtensionMetaSetting(IExtensionMeta from) + { + Name = from.Name; Version = from.Version; + } + public bool Equals([AllowNull] IExtensionMeta other) + { + return this.Name == other.Name && this.Version == other.Version; + } + } +} diff --git a/ProtocolMasterWPF/Model/MediaDevices.cs b/ProtocolMasterWPF/Model/MediaDevices.cs new file mode 100644 index 0000000..de01729 --- /dev/null +++ b/ProtocolMasterWPF/Model/MediaDevices.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Enumeration; + +namespace ProtocolMasterWPF.Model +{ + internal class MediaDevices : Observable + { + private static MediaDevices instance = new MediaDevices(); + public static MediaDevices Instance { get => instance; } + static MediaDevices() { } + private MediaDevices() + { + RefreshDevices(); + } + private DeviceInformationCollection _videoDevices; + + public DeviceInformationCollection VideoDevices + { + get => _videoDevices; + set + { + _videoDevices = value; + NotifyProperty(); + } + } + public void RefreshDevices() + { + Task task = DeviceInformation.FindAllAsync(DeviceClass.VideoCapture).AsTask(); + task.Wait(); + VideoDevices = task.Result; + task.Dispose(); + + task = DeviceInformation.FindAllAsync(DeviceClass.AudioCapture).AsTask(); + task.Wait(); + AudioDevices = task.Result; + } + private DeviceInformationCollection _audioDevices; + public DeviceInformationCollection AudioDevices + { + get => _audioDevices; + set + { + _audioDevices = value; + NotifyProperty(); + } + } + public DeviceInformation AudioDeviceByID(string id) + { + return AudioDevices.First(a => a.Id == id); + } + public DeviceInformation VideoDeviceByID(string id) + { + return VideoDevices.First(a => a.Id == id); + } + } +} diff --git a/ProtocolMasterWPF/Model/Session.cs b/ProtocolMasterWPF/Model/Session.cs index 610562e..3e26241 100644 --- a/ProtocolMasterWPF/Model/Session.cs +++ b/ProtocolMasterWPF/Model/Session.cs @@ -1,6 +1,7 @@ using ProtocolMasterCore.Protocol; using ProtocolMasterCore.Utility; using ProtocolMasterWPF.Helpers; +using ProtocolMasterWPF.Properties; using System; using System.Collections.Generic; using System.Linq; @@ -29,10 +30,38 @@ internal class Session : Observable CancellationToken CancelToken { get; set; } public List InterpreterOptions { get => _interpreterOptions; private set { _interpreterOptions = value; NotifyProperty(); } } private List _interpreterOptions; - public IExtensionMeta SelectedInterpreter { get => Protocol.InterpreterManager.Selected; set { Protocol.InterpreterManager.Selected = value; NotifyProperty(); } } + public IExtensionMeta SelectedInterpreter + { + get => Protocol.InterpreterManager.Selected; + set + { + if (value == null) return; + Protocol.InterpreterManager.Selected = value; + NotifyProperty(); + if (Settings.Default.InterpreterMeta != value) + { + Settings.Default.InterpreterMeta = new ExtensionMetaSetting(value); + Settings.Default.Save(); + } + } + } public List DriverOptions { get => _driverOptions; private set { _driverOptions = value; NotifyProperty(); } } private List _driverOptions; - public IExtensionMeta SelectedDriver { get => Protocol.DriverManager.Selected; set { Protocol.DriverManager.Selected = value; NotifyProperty(); } } + public IExtensionMeta SelectedDriver + { + get => Protocol.DriverManager.Selected; + set + { + if (value == null) return; + Protocol.DriverManager.Selected = value; + NotifyProperty(); + if (Settings.Default.DriverMeta != value) + { + Settings.Default.DriverMeta = new ExtensionMetaSetting(value); + Settings.Default.Save(); + } + } + } public ClockAnimator Animator { get; private set; } public CameraContainer Cam { get; private set; } SessionState State { get => _state; set { _state = value; NotifyStateProperties(); } } @@ -69,11 +98,44 @@ public Session() Protocol.InterpreterManager.OnEventsLoaded += Animator.FindMaxTime; Protocol.DriverManager.OnProtocolStart += Animator.StartAnimatorNow; Protocol.DriverManager.OnProtocolEnd += Animator.StopAnimator; - Protocol.LoadExtensions(); + + InitDefaultExtensions(); + + Cam = new CameraContainer(); OnStart += Cam.StartRecord; OnStop += Cam.StopRecord; } + public void InitDefaultExtensions() + { + Protocol.LoadExtensions(); + try + { + SelectedDriver = Settings.Default.DriverMeta; + } + catch (ArgumentException e) + { + Log.Error($"Default Driver could not be seleted, exception: {e}"); + SelectedDriver = Protocol.DriverManager.Selected; + } + catch (NullReferenceException) + { + SelectedDriver = Protocol.DriverManager.Selected; + } + try + { + SelectedInterpreter = Settings.Default.InterpreterMeta; + } + catch (ArgumentException e) + { + Log.Error($"Default Interpreter could not be seleted, exception: {e}"); + SelectedInterpreter = Protocol.InterpreterManager.Selected; + } + catch (NullReferenceException) + { + SelectedDriver = Protocol.DriverManager.Selected; + } + } private void LoadInterpreterOptions(List options) => InterpreterOptions = options; private void LoadDriverOptions(List options) => DriverOptions = options; private void NotifyStateProperties() @@ -105,7 +167,7 @@ public void Start(bool overrideCheck = false) OnRun?.Invoke(); Protocol.Run(); } - if(!CancelToken.IsCancellationRequested) + if (!CancelToken.IsCancellationRequested) Stop(); }, CancelSource.Token); SessionTask.Start(); diff --git a/ProtocolMasterWPF/Properties/Settings.Designer.cs b/ProtocolMasterWPF/Properties/Settings.Designer.cs index 723439d..9abb4c8 100644 --- a/ProtocolMasterWPF/Properties/Settings.Designer.cs +++ b/ProtocolMasterWPF/Properties/Settings.Designer.cs @@ -26,12 +26,58 @@ public static Settings Default { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] - public string SessionConfig { + public string CameraID { get { - return ((string)(this["SessionConfig"])); + return ((string)(this["CameraID"])); } set { - this["SessionConfig"] = value; + this["CameraID"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string MicrophoneID { + get { + return ((string)(this["MicrophoneID"])); + } + set { + this["MicrophoneID"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::ProtocolMasterWPF.Model.ExtensionMetaSetting DriverMeta { + get { + return ((global::ProtocolMasterWPF.Model.ExtensionMetaSetting)(this["DriverMeta"])); + } + set { + this["DriverMeta"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::ProtocolMasterWPF.Model.ExtensionMetaSetting InterpreterMeta { + get { + return ((global::ProtocolMasterWPF.Model.ExtensionMetaSetting)(this["InterpreterMeta"])); + } + set { + this["InterpreterMeta"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ExperimentDefaultTab { + get { + return ((string)(this["ExperimentDefaultTab"])); + } + set { + this["ExperimentDefaultTab"] = value; } } } diff --git a/ProtocolMasterWPF/Properties/Settings.settings b/ProtocolMasterWPF/Properties/Settings.settings index 5e7af51..6a6e335 100644 --- a/ProtocolMasterWPF/Properties/Settings.settings +++ b/ProtocolMasterWPF/Properties/Settings.settings @@ -2,7 +2,19 @@ - + + + + + + + + + + + + + diff --git a/ProtocolMasterWPF/ProtocolMasterWPF.csproj b/ProtocolMasterWPF/ProtocolMasterWPF.csproj index 54ee78b..7cea15d 100644 --- a/ProtocolMasterWPF/ProtocolMasterWPF.csproj +++ b/ProtocolMasterWPF/ProtocolMasterWPF.csproj @@ -6,6 +6,9 @@ true Assets\Logo\LogoSquareIcon.ico app.manifest + 2021.1 + false + false @@ -15,6 +18,7 @@ x64 + false diff --git a/ProtocolMasterWPF/Settings.cs b/ProtocolMasterWPF/Settings.cs new file mode 100644 index 0000000..aac3792 --- /dev/null +++ b/ProtocolMasterWPF/Settings.cs @@ -0,0 +1,28 @@ +namespace ProtocolMasterWPF.Properties { + + + // This class allows you to handle specific events on the settings class: + // The SettingChanging event is raised before a setting's value is changed. + // The PropertyChanged event is raised after a setting's value is changed. + // The SettingsLoaded event is raised after the setting values are loaded. + // The SettingsSaving event is raised before the setting values are saved. + internal sealed partial class Settings { + + public Settings() { + // // To add event handlers for saving and changing settings, uncomment the lines below: + // + // this.SettingChanging += this.SettingChangingEventHandler; + // + // this.SettingsSaving += this.SettingsSavingEventHandler; + // + } + + private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { + // Add code to handle the SettingChangingEvent event here. + } + + private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) { + // Add code to handle the SettingsSaving event here. + } + } +} diff --git a/ProtocolMasterWPF/View/ProtocolSelectView.xaml b/ProtocolMasterWPF/View/ProtocolSelectView.xaml index f58f0d8..ad899c2 100644 --- a/ProtocolMasterWPF/View/ProtocolSelectView.xaml +++ b/ProtocolMasterWPF/View/ProtocolSelectView.xaml @@ -8,7 +8,7 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - @@ -70,7 +70,7 @@