Романенко Никита Станиславович
6 years ago
34 changed files with 1381 additions and 0 deletions
@ -0,0 +1,25 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
# Visual Studio 15 |
||||
|
VisualStudioVersion = 15.0.28307.106 |
||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignalsMVVM", "SignalsMVVM\SignalsMVVM.csproj", "{2F55AE30-8FA0-4175-83EB-236D1026F97D}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{2F55AE30-8FA0-4175-83EB-236D1026F97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{2F55AE30-8FA0-4175-83EB-236D1026F97D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{2F55AE30-8FA0-4175-83EB-236D1026F97D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{2F55AE30-8FA0-4175-83EB-236D1026F97D}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
|
SolutionGuid = {EA5876EF-4AE7-40A4-AD8B-F47587567B11} |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
@ -0,0 +1,6 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<configuration> |
||||
|
<startup> |
||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> |
||||
|
</startup> |
||||
|
</configuration> |
@ -0,0 +1,15 @@ |
|||||
|
<Application x:Class="SignalsMVVM.App" |
||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:SignalsMVVM" |
||||
|
StartupUri="MainWindow.xaml" |
||||
|
xmlns:model="clr-namespace:SignalsMVVM.Models"> |
||||
|
<Application.Resources> |
||||
|
<ResourceDictionary> |
||||
|
<ResourceDictionary.MergedDictionaries> |
||||
|
<ResourceDictionary Source="Assets/Templates.xaml"/> |
||||
|
<ResourceDictionary Source="Assets/Styles.xaml"/> |
||||
|
</ResourceDictionary.MergedDictionaries> |
||||
|
</ResourceDictionary> |
||||
|
</Application.Resources> |
||||
|
</Application> |
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Configuration; |
||||
|
using System.Data; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace SignalsMVVM |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Interaction logic for App.xaml
|
||||
|
/// </summary>
|
||||
|
public partial class App : Application |
||||
|
{ |
||||
|
} |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:SignalsMVVM.Assets"> |
||||
|
|
||||
|
<Style TargetType="TextBlock"> |
||||
|
<Setter Property="FontSize" Value="15"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style TargetType="TextBox"> |
||||
|
<Setter Property="FontSize" Value="13"/> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
@ -0,0 +1,32 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:SignalsMVVM.Assets" |
||||
|
xmlns:model="clr-namespace:SignalsMVVM.Models" |
||||
|
xmlns:converters="clr-namespace:SignalsMVVM.UI.Converters"> |
||||
|
|
||||
|
<converters:HertzConverter x:Key="HertzConverter"/> |
||||
|
<DataTemplate DataType="{x:Type model:AmSignal}"> |
||||
|
<StackPanel Margin="10" Grid.Column="0" Grid.Row="1"> |
||||
|
<TextBlock Text="AmplModValue: "/> |
||||
|
<TextBox Text="{Binding AmplModValue}"/> |
||||
|
<TextBlock Text="Частота: "/> |
||||
|
<TextBox Text="{Binding Frequency, Converter={StaticResource HertzConverter}}"/> |
||||
|
<TextBlock Text="Задержка: "/> |
||||
|
<TextBox Text="{Binding Delay}"/> |
||||
|
<TextBlock Text="Амплитуда: "/> |
||||
|
<TextBox Text="{Binding Amplitude}"/> |
||||
|
</StackPanel> |
||||
|
</DataTemplate> |
||||
|
<DataTemplate DataType="{x:Type model:FmSignal}"> |
||||
|
<StackPanel Margin="10" Grid.Column="0" Grid.Row="1"> |
||||
|
<TextBlock Text="FreqModValue: "/> |
||||
|
<TextBox Text="{Binding FreqModValue}"/> |
||||
|
<TextBlock Text="Частота: "/> |
||||
|
<TextBox Text="{Binding Frequency, Converter={StaticResource HertzConverter}}"/> |
||||
|
<TextBlock Text="Задержка: "/> |
||||
|
<TextBox Text="{Binding Delay}"/> |
||||
|
<TextBlock Text="Амплитуда: "/> |
||||
|
<TextBox Text="{Binding Amplitude}"/> |
||||
|
</StackPanel> |
||||
|
</DataTemplate> |
||||
|
</ResourceDictionary> |
@ -0,0 +1,5 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<Costura /> |
||||
|
<PropertyChanged /> |
||||
|
</Weavers> |
@ -0,0 +1,135 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuild. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="EventInvokerNames" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="CheckForEquality" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
<xs:element name="Costura" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:element> |
||||
|
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:element> |
||||
|
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:element> |
||||
|
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:element> |
||||
|
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="DisableCompression" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="DisableCleanup" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="LoadAtModuleInit" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="ExcludeAssemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="IncludeAssemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="Unmanaged32Assemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="Unmanaged64Assemblies" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="PreloadOrder" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification on the target assembly after all weavers have been finished.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
@ -0,0 +1,30 @@ |
|||||
|
using System.IO; |
||||
|
using System.Runtime.Serialization.Formatters.Binary; |
||||
|
|
||||
|
namespace SignalsMVVM.HelperClasses |
||||
|
{ |
||||
|
public static class BinaryFormatterSerialization |
||||
|
{ |
||||
|
static private BinaryFormatter serializer = new BinaryFormatter(); |
||||
|
|
||||
|
public static T DeepCloneBinaryFormatter<T>(this T obj) |
||||
|
{ |
||||
|
return obj.SerializeBinaryFormatter().DeserializeBinaryFormatter<T>(); |
||||
|
} |
||||
|
|
||||
|
public static byte[] SerializeBinaryFormatter<T>(this T obj) |
||||
|
{ |
||||
|
using (var ms = new MemoryStream()) |
||||
|
{ |
||||
|
serializer.Serialize(ms, obj); |
||||
|
return ms.ToArray(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static T DeserializeBinaryFormatter<T>(this byte[] data) |
||||
|
{ |
||||
|
using (var ms = new MemoryStream(data, false)) |
||||
|
return (T)serializer.Deserialize(ms); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SignalsMVVM.HelperClasses |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class PropertyChangedClass : INotifyPropertyChanged |
||||
|
{ |
||||
|
[field: NonSerialized] |
||||
|
public virtual event PropertyChangedEventHandler PropertyChanged; |
||||
|
|
||||
|
public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) |
||||
|
{ |
||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); |
||||
|
} |
||||
|
|
||||
|
public virtual void OnPropertyChanged(params string[] propertyNames) |
||||
|
{ |
||||
|
foreach (var property in propertyNames) |
||||
|
OnPropertyChanged(property); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Input; |
||||
|
|
||||
|
namespace SignalsMVVM.HelperClasses |
||||
|
{ |
||||
|
public class RelayCommand<T> : ICommand |
||||
|
{ |
||||
|
protected Action<T> _execute; |
||||
|
protected Func<T, bool> _canExecute; |
||||
|
|
||||
|
protected RelayCommand() { } |
||||
|
|
||||
|
public RelayCommand(Action<T> execute, Func<T, bool> canExecute) |
||||
|
{ |
||||
|
if (execute == null) |
||||
|
throw new ArgumentNullException(nameof(execute)); |
||||
|
|
||||
|
_execute = execute; |
||||
|
_canExecute = canExecute ?? (p => true); |
||||
|
} |
||||
|
|
||||
|
public RelayCommand(Action<T> execute) : this(execute, (Func<T, bool>)null) { } |
||||
|
public RelayCommand(Action<T> execute, Func<bool> canExecute) : this(execute, p => canExecute()) { } |
||||
|
|
||||
|
public event EventHandler CanExecuteChanged |
||||
|
{ |
||||
|
add { CommandManager.RequerySuggested += value; } |
||||
|
remove { CommandManager.RequerySuggested -= value; } |
||||
|
} |
||||
|
|
||||
|
public void Execute(object parameter) => _execute((T)parameter); |
||||
|
public bool CanExecute(object parameter) => _canExecute((T)parameter); |
||||
|
} |
||||
|
|
||||
|
public class RelayCommand : RelayCommand<object> |
||||
|
{ |
||||
|
public RelayCommand(Action<object> execute, Func<object, bool> canExecute) : base(execute, canExecute) { } |
||||
|
|
||||
|
public RelayCommand(Action execute) : base(p => execute()) { } |
||||
|
public RelayCommand(Action execute, Func<bool> canExecute) : base(p => execute(), p => canExecute()) { } |
||||
|
|
||||
|
public RelayCommand(Action<object> execute) : base(execute) { } |
||||
|
public RelayCommand(Action<object> execute, Func<bool> canExecute) : base(execute, canExecute) { } |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace SignalsMVVM.Interfaces |
||||
|
{ |
||||
|
public interface IGraphicControl |
||||
|
{ |
||||
|
void ClearGraphic(); |
||||
|
void DrawLine(double X1, double Y1, double X2, double Y2); |
||||
|
} |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
namespace SignalsMVVM.Interfaces |
||||
|
{ |
||||
|
public interface IProcedureLogger |
||||
|
{ |
||||
|
void ExecuteThread(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
using SignalsMVVM.Models; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace SignalsMVVM.Interfaces |
||||
|
{ |
||||
|
public interface ISignalLoader |
||||
|
{ |
||||
|
IList<BaseSignal> LoadSignals(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
using SignalsMVVM.Models; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace SignalsMVVM.Interfaces |
||||
|
{ |
||||
|
public interface ISignalSaver |
||||
|
{ |
||||
|
void SaveSignals(IList<BaseSignal> signals); |
||||
|
} |
||||
|
} |
@ -0,0 +1,106 @@ |
|||||
|
using SignalsMVVM.Models; |
||||
|
using SignalsMVVM.HelperClasses; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Threading; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Threading; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using SignalsMVVM.Interfaces; |
||||
|
using Autofac; |
||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace SignalsMVVM |
||||
|
{ |
||||
|
public class MainVM : PropertyChangedClass |
||||
|
{ |
||||
|
public IList<BaseSignal> SignalPrototypes { get; set; } |
||||
|
public IList<BaseSignal> ListOfSignals { get; set; } |
||||
|
public IList<BaseSignal> ExecutionLog { get; set; } |
||||
|
|
||||
|
public BaseSignal SelectedSignalPrototype { get; set; } |
||||
|
public BaseSignal SelectedSignalInList { get; set; } |
||||
|
|
||||
|
public RelayCommand AddNewSignalToList { get; set; } |
||||
|
public RelayCommand RemoveSelectedSignalFromList { get; set; } |
||||
|
public RelayCommand StartProcedure { get; set; } |
||||
|
public RelayCommand AbortExecution { get; set; } |
||||
|
public RelayCommand SaveSettings { get; set; } |
||||
|
public RelayCommand LoadSettings { get; set; } |
||||
|
|
||||
|
public GeometryCollection CanvasGeometries { get; set; } |
||||
|
|
||||
|
public bool IsBusy { get; set; } |
||||
|
|
||||
|
private Thread CurrentThread; |
||||
|
|
||||
|
private Dispatcher dispatcher; |
||||
|
|
||||
|
private IContainer Container { get; set; } |
||||
|
|
||||
|
public MainVM() |
||||
|
{ |
||||
|
SignalPrototypes = new ObservableCollection<BaseSignal>(); |
||||
|
SignalPrototypes.Add(new AmSignal("AM сигнал")); |
||||
|
SignalPrototypes.Add(new FmSignal("FM сигнал")); |
||||
|
ListOfSignals = new ObservableCollection<BaseSignal>(); |
||||
|
ExecutionLog = new ObservableCollection<BaseSignal>(); |
||||
|
CanvasGeometries = new GeometryCollection(); |
||||
|
|
||||
|
AddNewSignalToList = new RelayCommand(AddNew, () => { if (IsBusy) return false; return SelectedSignalPrototype != null; }); |
||||
|
RemoveSelectedSignalFromList = |
||||
|
new RelayCommand(RemoveSignalFromList, () => { if (IsBusy) return false; return SelectedSignalInList != null; }); |
||||
|
StartProcedure = new RelayCommand(Start, () => { if (IsBusy) return false; return ListOfSignals.Count > 0; }); |
||||
|
AbortExecution = new RelayCommand(AbortThreadExecution, () => IsBusy); |
||||
|
SaveSettings = new RelayCommand(SaveSettingsToFile, () => { if (IsBusy) return false; return ListOfSignals.Count > 0; }); |
||||
|
LoadSettings = new RelayCommand(LoadSettingsFromFile, () => !IsBusy); |
||||
|
|
||||
|
var builder = new ContainerBuilder(); |
||||
|
builder.RegisterType<SignalController>().As<ISignalLoader>().As<ISignalSaver>(); |
||||
|
builder.RegisterInstance(new GraphicController(CanvasGeometries)).As<IGraphicControl>(); |
||||
|
Container = builder.Build(); |
||||
|
|
||||
|
dispatcher = Application.Current.Dispatcher; |
||||
|
|
||||
|
Action a = () => |
||||
|
{ |
||||
|
Container.Resolve<IGraphicControl>().DrawLine(0, 0, 100, 100); |
||||
|
}; |
||||
|
a.Invoke(); |
||||
|
} |
||||
|
|
||||
|
private void AddNew() |
||||
|
{ |
||||
|
ListOfSignals.Add((BaseSignal)SelectedSignalPrototype.Clone()); |
||||
|
} |
||||
|
|
||||
|
private void RemoveSignalFromList() |
||||
|
{ |
||||
|
ListOfSignals.Remove(SelectedSignalInList); |
||||
|
} |
||||
|
|
||||
|
private void Start() |
||||
|
{ |
||||
|
ExecutionLog.Clear(); |
||||
|
IProcedureLogger logger = new LogController(dispatcher, ListOfSignals, ExecutionLog, (value) => IsBusy = value); |
||||
|
CurrentThread = new Thread(logger.ExecuteThread); |
||||
|
CurrentThread.Start(); |
||||
|
} |
||||
|
|
||||
|
private void AbortThreadExecution() |
||||
|
{ |
||||
|
CurrentThread.Abort(); |
||||
|
IsBusy = false; |
||||
|
} |
||||
|
|
||||
|
private void SaveSettingsToFile() |
||||
|
{ |
||||
|
Container.Resolve<ISignalSaver>().SaveSignals(ListOfSignals); |
||||
|
} |
||||
|
|
||||
|
private void LoadSettingsFromFile() |
||||
|
{ |
||||
|
ListOfSignals = Container.Resolve<ISignalLoader>().LoadSignals(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,126 @@ |
|||||
|
<Window x:Class="SignalsMVVM.MainWindow" |
||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
|
xmlns:local="clr-namespace:SignalsMVVM" |
||||
|
xmlns:model="clr-namespace:SignalsMVVM.Models" |
||||
|
xmlns:converters="clr-namespace:SignalsMVVM.UI.Converters" |
||||
|
mc:Ignorable="d" |
||||
|
Title="MainWindow" Height="700" Width="1200" WindowState="Maximized" ResizeMode="NoResize"> |
||||
|
<Grid Margin="10"> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="2*"/> |
||||
|
<ColumnDefinition Width="2*"/> |
||||
|
<ColumnDefinition Width="1*"/> |
||||
|
<ColumnDefinition Width="1*"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="1*"/> |
||||
|
<RowDefinition Height="1*"/> |
||||
|
<RowDefinition Height="40"/> |
||||
|
<RowDefinition Height="40"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<ContentControl Content="{Binding SelectedSignalPrototype}" |
||||
|
Grid.Column="0" Grid.Row="1"/> |
||||
|
|
||||
|
<Button x:Name="AddSignalButton" Content="Добавить сигнал" Grid.Column="0" Grid.Row="2" |
||||
|
Command="{Binding AddNewSignalToList}"/> |
||||
|
<Button x:Name="RemoveSignalButton" Content="Удалить сигнал" Grid.Column="1" Grid.Row="2" |
||||
|
Command="{Binding RemoveSelectedSignalFromList}"/> |
||||
|
<Button x:Name="ExecuteSignals" Content="Выполнить процедуру" Grid.Column="2" Grid.Row="2" |
||||
|
Command="{Binding StartProcedure}"/> |
||||
|
<Button x:Name="AbortExecutionButton" Content="Прервать процедуру" Grid.Column="3" Grid.Row="2" |
||||
|
Command="{Binding AbortExecution}"/> |
||||
|
<Button x:Name="SaveSettingsButton" Content="Сохранить сигналы" Grid.Column="2" Grid.Row="3" |
||||
|
Command="{Binding SaveSettings}"/> |
||||
|
<Button x:Name="LoadSettingsButton" Content="Загрузить сигналы" Grid.Column="3" Grid.Row="3" |
||||
|
Command="{Binding LoadSettings}"/> |
||||
|
|
||||
|
<ListBox x:Name="SignalPrototypesListView" Grid.Column="0" Grid.Row="0" |
||||
|
ItemsSource="{Binding SignalPrototypes}" |
||||
|
SelectedItem="{Binding SelectedSignalPrototype}"> |
||||
|
<ListBox.ItemContainerStyle> |
||||
|
<Style TargetType="ListBoxItem"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate> |
||||
|
<Border x:Name="PART_Container" BorderThickness="0,0,0,1"> |
||||
|
<TextBlock Text="{Binding Name}"/> |
||||
|
</Border> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="IsMouseOver" |
||||
|
Value="true"> |
||||
|
<Setter TargetName="PART_Container" Property="BorderBrush" Value="Black"/> |
||||
|
</Trigger> |
||||
|
<Trigger Property="ListBoxItem.IsSelected" |
||||
|
Value="true"> |
||||
|
<Setter TargetName="PART_Container" Property="BorderBrush" Value="Red"/> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
</ListBox.ItemContainerStyle> |
||||
|
</ListBox> |
||||
|
|
||||
|
<ListBox x:Name="ExistingSignalsListView" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" |
||||
|
ItemsSource="{Binding ListOfSignals}" |
||||
|
SelectedItem="{Binding SelectedSignalInList}"> |
||||
|
<ListBox.ItemContainerStyle> |
||||
|
<Style TargetType="ListBoxItem"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate> |
||||
|
<Border x:Name="BORDER_SignalListItem" BorderBrush="Aquamarine" BorderThickness="1"> |
||||
|
<TextBlock Text="{Binding Name}"/> |
||||
|
</Border> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="IsMouseOver" Value="true"> |
||||
|
<Setter TargetName="BORDER_SignalListItem" Property="BorderBrush" Value="Blue"/> |
||||
|
</Trigger> |
||||
|
<Trigger Property="ListBoxItem.IsSelected" Value="true"> |
||||
|
<Setter TargetName="BORDER_SignalListItem" Property="BorderBrush" Value="Black"/> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
</ListBox.ItemContainerStyle> |
||||
|
</ListBox> |
||||
|
|
||||
|
|
||||
|
<ListBox x:Name="ExecutionLogListBox" Grid.Column="2" Grid.Row="0" Grid.RowSpan="1" Grid.ColumnSpan="2" ItemsSource="{Binding ExecutionLog}"> |
||||
|
<ListBox.ItemContainerStyle> |
||||
|
<Style TargetType="ListBoxItem"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate> |
||||
|
<TextBlock> |
||||
|
<TextBlock.Text> |
||||
|
<MultiBinding StringFormat="{}{0} задержка = {1}"> |
||||
|
<Binding Path="Name"/> |
||||
|
<Binding Path="Delay"/> |
||||
|
</MultiBinding> |
||||
|
</TextBlock.Text> |
||||
|
</TextBlock> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
</ListBox.ItemContainerStyle> |
||||
|
</ListBox> |
||||
|
|
||||
|
<Canvas Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="1"> |
||||
|
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF"> |
||||
|
<Path.Data> |
||||
|
<GeometryGroup Children="{Binding CanvasGeometries}"/> |
||||
|
</Path.Data> |
||||
|
</Path> |
||||
|
</Canvas> |
||||
|
|
||||
|
</Grid> |
||||
|
</Window> |
@ -0,0 +1,13 @@ |
|||||
|
using System.Windows; |
||||
|
|
||||
|
namespace SignalsMVVM |
||||
|
{ |
||||
|
public partial class MainWindow : Window |
||||
|
{ |
||||
|
public MainWindow() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
DataContext = new MainVM(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace SignalsMVVM.Models |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class AmSignal : BaseSignal |
||||
|
{ |
||||
|
public double AmplModValue { get; set; } |
||||
|
public AmSignal(string Name) : base (Name) { } |
||||
|
} |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using SignalsMVVM.HelperClasses; |
||||
|
|
||||
|
namespace SignalsMVVM.Models |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public abstract class BaseSignal : PropertyChangedClass, ICloneable |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public int Delay { get; set; } |
||||
|
public double Amplitude { get; set; } |
||||
|
public double Frequency { get; set; } |
||||
|
|
||||
|
public BaseSignal(string Name) |
||||
|
{ |
||||
|
this.Name = Name; |
||||
|
} |
||||
|
|
||||
|
public object Clone() |
||||
|
{ |
||||
|
return this.DeepCloneBinaryFormatter(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace SignalsMVVM.Models |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class FmSignal : BaseSignal |
||||
|
{ |
||||
|
public double FreqModValue { get; set; } |
||||
|
public FmSignal(string Name) : base(Name) { } |
||||
|
} |
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
using System.Windows; |
||||
|
using System.Windows.Media; |
||||
|
using SignalsMVVM.Interfaces; |
||||
|
|
||||
|
namespace SignalsMVVM.Models |
||||
|
{ |
||||
|
public class GraphicController : IGraphicControl |
||||
|
{ |
||||
|
private GeometryCollection geometries; |
||||
|
|
||||
|
public void ClearGraphic() |
||||
|
{ |
||||
|
geometries.Clear(); |
||||
|
} |
||||
|
|
||||
|
public void DrawLine(double X1, double Y1, double X2, double Y2) |
||||
|
{ |
||||
|
var p1 = new Point(X1, Y1); |
||||
|
var p2 = new Point(X2, Y2); |
||||
|
geometries.Add(new LineGeometry(p1, p2)); |
||||
|
} |
||||
|
|
||||
|
public GraphicController(GeometryCollection geometries) |
||||
|
{ |
||||
|
this.geometries = geometries; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading; |
||||
|
using System.Windows.Threading; |
||||
|
using SignalsMVVM.Interfaces; |
||||
|
|
||||
|
namespace SignalsMVVM.Models |
||||
|
{ |
||||
|
public class LogController : IProcedureLogger |
||||
|
{ |
||||
|
private Action<bool> IsThreadAlive { get; set; } |
||||
|
private Dispatcher MainDispatcher { get; set; } |
||||
|
private IList<BaseSignal> InputList { get; set; } |
||||
|
private IList<BaseSignal> OutputList { get; set; } |
||||
|
|
||||
|
public LogController(Dispatcher dispatcher, IList<BaseSignal> inputList, IList<BaseSignal> outputList, Action<bool> isThreadAlive) |
||||
|
{ |
||||
|
MainDispatcher = dispatcher; |
||||
|
InputList = inputList; |
||||
|
OutputList = outputList; |
||||
|
IsThreadAlive = isThreadAlive; |
||||
|
} |
||||
|
|
||||
|
public void ExecuteThread() |
||||
|
{ |
||||
|
IsThreadAlive(true); |
||||
|
foreach (BaseSignal signal in InputList) |
||||
|
{ |
||||
|
MainDispatcher.Invoke(() => OutputList.Add(signal)); |
||||
|
Thread.Sleep(signal.Delay); |
||||
|
} |
||||
|
IsThreadAlive(false); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
using Microsoft.Win32; |
||||
|
using SignalsMVVM.HelperClasses; |
||||
|
using SignalsMVVM.Interfaces; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace SignalsMVVM.Models |
||||
|
{ |
||||
|
public class SignalController : ISignalLoader, ISignalSaver |
||||
|
{ |
||||
|
public IList<BaseSignal> LoadSignals() |
||||
|
{ |
||||
|
OpenFileDialog dialog = new OpenFileDialog(); |
||||
|
IList<BaseSignal> signalList = new List<BaseSignal>(); |
||||
|
if (dialog.ShowDialog() == true) |
||||
|
try |
||||
|
{ |
||||
|
var byteArray = File.ReadAllBytes(dialog.FileName); |
||||
|
signalList = BinaryFormatterSerialization.DeserializeBinaryFormatter<IList<BaseSignal>>(byteArray); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
MessageBox.Show(ex.Message); |
||||
|
} |
||||
|
return signalList; |
||||
|
} |
||||
|
|
||||
|
public void SaveSignals(IList<BaseSignal> signals) |
||||
|
{ |
||||
|
SaveFileDialog dialog = new SaveFileDialog(); |
||||
|
if (dialog.ShowDialog() != true) return; |
||||
|
try |
||||
|
{ |
||||
|
File.WriteAllBytes(dialog.FileName, |
||||
|
BinaryFormatterSerialization.SerializeBinaryFormatter(signals)); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
MessageBox.Show(ex.Message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
using System.Reflection; |
||||
|
using System.Resources; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Windows; |
||||
|
|
||||
|
// General Information about an assembly is controlled through the following
|
||||
|
// set of attributes. Change these attribute values to modify the information
|
||||
|
// associated with an assembly.
|
||||
|
[assembly: AssemblyTitle("SignalsMVVM")] |
||||
|
[assembly: AssemblyDescription("")] |
||||
|
[assembly: AssemblyConfiguration("")] |
||||
|
[assembly: AssemblyCompany("")] |
||||
|
[assembly: AssemblyProduct("SignalsMVVM")] |
||||
|
[assembly: AssemblyCopyright("Copyright © 2018")] |
||||
|
[assembly: AssemblyTrademark("")] |
||||
|
[assembly: AssemblyCulture("")] |
||||
|
|
||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
|
// to COM components. If you need to access a type in this assembly from
|
||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||
|
[assembly: ComVisible(false)] |
||||
|
|
||||
|
//In order to begin building localizable applications, set
|
||||
|
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
|
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
|
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
|
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
|
//the line below to match the UICulture setting in the project file.
|
||||
|
|
||||
|
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
|
||||
|
|
||||
|
[assembly: ThemeInfo( |
||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// or application resource dictionaries)
|
||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// app, or any theme specific resource dictionaries)
|
||||
|
)] |
||||
|
|
||||
|
|
||||
|
// Version information for an assembly consists of the following four values:
|
||||
|
//
|
||||
|
// Major Version
|
||||
|
// Minor Version
|
||||
|
// Build Number
|
||||
|
// Revision
|
||||
|
//
|
||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
|
// by using the '*' as shown below:
|
||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
[assembly: AssemblyVersion("1.0.0.0")] |
||||
|
[assembly: AssemblyFileVersion("1.0.0.0")] |
@ -0,0 +1,71 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace SignalsMVVM.Properties |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources |
||||
|
{ |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if ((resourceMan == null)) |
||||
|
{ |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SignalsMVVM.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set |
||||
|
{ |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
</root> |
@ -0,0 +1,30 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace SignalsMVVM.Properties |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] |
||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase |
||||
|
{ |
||||
|
|
||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
||||
|
|
||||
|
public static Settings Default |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return defaultInstance; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
<?xml version='1.0' encoding='utf-8'?> |
||||
|
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> |
||||
|
<Profiles> |
||||
|
<Profile Name="(Default)" /> |
||||
|
</Profiles> |
||||
|
<Settings /> |
||||
|
</SettingsFile> |
@ -0,0 +1,155 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<Import Project="..\packages\PropertyChanged.Fody.2.6.0\build\PropertyChanged.Fody.props" Condition="Exists('..\packages\PropertyChanged.Fody.2.6.0\build\PropertyChanged.Fody.props')" /> |
||||
|
<Import Project="..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props')" /> |
||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
||||
|
<PropertyGroup> |
||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
|
<ProjectGuid>{2F55AE30-8FA0-4175-83EB-236D1026F97D}</ProjectGuid> |
||||
|
<OutputType>WinExe</OutputType> |
||||
|
<RootNamespace>SignalsMVVM</RootNamespace> |
||||
|
<AssemblyName>SignalsMVVM</AssemblyName> |
||||
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> |
||||
|
<FileAlignment>512</FileAlignment> |
||||
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> |
||||
|
<Deterministic>true</Deterministic> |
||||
|
<NuGetPackageImportStamp> |
||||
|
</NuGetPackageImportStamp> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
|
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
|
<DebugSymbols>true</DebugSymbols> |
||||
|
<DebugType>full</DebugType> |
||||
|
<Optimize>false</Optimize> |
||||
|
<OutputPath>bin\Debug\</OutputPath> |
||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
|
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
|
<DebugType>pdbonly</DebugType> |
||||
|
<Optimize>true</Optimize> |
||||
|
<OutputPath>bin\Release\</OutputPath> |
||||
|
<DefineConstants>TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<Reference Include="Autofac, Version=4.8.1.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL"> |
||||
|
<HintPath>..\packages\Autofac.4.8.1\lib\net45\Autofac.dll</HintPath> |
||||
|
</Reference> |
||||
|
<Reference Include="Costura, Version=3.2.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL"> |
||||
|
<HintPath>..\packages\Costura.Fody.3.2.0\lib\net46\Costura.dll</HintPath> |
||||
|
</Reference> |
||||
|
<Reference Include="PropertyChanged, Version=2.6.0.0, Culture=neutral, PublicKeyToken=ee3ee20bcf148ddd, processorArchitecture=MSIL"> |
||||
|
<HintPath>..\packages\PropertyChanged.Fody.2.6.0\lib\net452\PropertyChanged.dll</HintPath> |
||||
|
</Reference> |
||||
|
<Reference Include="System" /> |
||||
|
<Reference Include="System.Data" /> |
||||
|
<Reference Include="System.Xml" /> |
||||
|
<Reference Include="Microsoft.CSharp" /> |
||||
|
<Reference Include="System.Core" /> |
||||
|
<Reference Include="System.Xml.Linq" /> |
||||
|
<Reference Include="System.Data.DataSetExtensions" /> |
||||
|
<Reference Include="System.Net.Http" /> |
||||
|
<Reference Include="System.Xaml"> |
||||
|
<RequiredTargetFramework>4.0</RequiredTargetFramework> |
||||
|
</Reference> |
||||
|
<Reference Include="WindowsBase" /> |
||||
|
<Reference Include="PresentationCore" /> |
||||
|
<Reference Include="PresentationFramework" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ApplicationDefinition Include="App.xaml"> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
<SubType>Designer</SubType> |
||||
|
</ApplicationDefinition> |
||||
|
<Compile Include="HelperClasses\BinaryFormatterSerialization.cs" /> |
||||
|
<Compile Include="Interfaces\IGraphicControl.cs" /> |
||||
|
<Compile Include="Interfaces\IProcedureLogger.cs" /> |
||||
|
<Compile Include="Interfaces\ISignalLoader.cs" /> |
||||
|
<Compile Include="Interfaces\ISignalSaver.cs" /> |
||||
|
<Compile Include="Models\GraphicController.cs" /> |
||||
|
<Compile Include="Models\LogController.cs" /> |
||||
|
<Compile Include="Models\SignalController.cs" /> |
||||
|
<Compile Include="UI\Converters\HertzConverter.cs" /> |
||||
|
<Compile Include="UserControl1.xaml.cs"> |
||||
|
<DependentUpon>UserControl1.xaml</DependentUpon> |
||||
|
</Compile> |
||||
|
<Page Include="Assets\Styles.xaml"> |
||||
|
<SubType>Designer</SubType> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
</Page> |
||||
|
<Page Include="Assets\Templates.xaml"> |
||||
|
<SubType>Designer</SubType> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
</Page> |
||||
|
<Page Include="MainWindow.xaml"> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
<SubType>Designer</SubType> |
||||
|
</Page> |
||||
|
<Compile Include="App.xaml.cs"> |
||||
|
<DependentUpon>App.xaml</DependentUpon> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
<Compile Include="MainVM.cs" /> |
||||
|
<Compile Include="Models\AmSignal.cs" /> |
||||
|
<Compile Include="Models\BaseSignal.cs" /> |
||||
|
<Compile Include="HelperClasses\PropertyChanged.cs" /> |
||||
|
<Compile Include="HelperClasses\RelayCommand.cs" /> |
||||
|
<Compile Include="MainWindow.xaml.cs"> |
||||
|
<DependentUpon>MainWindow.xaml</DependentUpon> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
<Page Include="UserControl1.xaml"> |
||||
|
<SubType>Designer</SubType> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
</Page> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Compile Include="Models\FmSignal.cs" /> |
||||
|
<Compile Include="Properties\AssemblyInfo.cs"> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
<Compile Include="Properties\Resources.Designer.cs"> |
||||
|
<AutoGen>True</AutoGen> |
||||
|
<DesignTime>True</DesignTime> |
||||
|
<DependentUpon>Resources.resx</DependentUpon> |
||||
|
</Compile> |
||||
|
<Compile Include="Properties\Settings.Designer.cs"> |
||||
|
<AutoGen>True</AutoGen> |
||||
|
<DependentUpon>Settings.settings</DependentUpon> |
||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput> |
||||
|
</Compile> |
||||
|
<EmbeddedResource Include="Properties\Resources.resx"> |
||||
|
<Generator>ResXFileCodeGenerator</Generator> |
||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput> |
||||
|
</EmbeddedResource> |
||||
|
<None Include="packages.config" /> |
||||
|
<None Include="Properties\Settings.settings"> |
||||
|
<Generator>SettingsSingleFileGenerator</Generator> |
||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput> |
||||
|
</None> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<None Include="App.config" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Resource Include="FodyWeavers.xml" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup /> |
||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
|
<Import Project="..\packages\Fody.3.3.2\build\Fody.targets" Condition="Exists('..\packages\Fody.3.3.2\build\Fody.targets')" /> |
||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
||||
|
<PropertyGroup> |
||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> |
||||
|
</PropertyGroup> |
||||
|
<Error Condition="!Exists('..\packages\Fody.3.3.2\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.3.3.2\build\Fody.targets'))" /> |
||||
|
<Error Condition="!Exists('..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props'))" /> |
||||
|
<Error Condition="!Exists('..\packages\PropertyChanged.Fody.2.6.0\build\PropertyChanged.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\PropertyChanged.Fody.2.6.0\build\PropertyChanged.Fody.props'))" /> |
||||
|
</Target> |
||||
|
</Project> |
@ -0,0 +1,112 @@ |
|||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace SignalsMVVM.UI.Converters |
||||
|
{ |
||||
|
[ValueConversion(typeof(double), typeof(string))] |
||||
|
public class HertzConverter : IValueConverter |
||||
|
{ |
||||
|
static string[] keys = new string[] { "Гц", "кГц", "МГц", "ГГц" }; |
||||
|
static string[] keys_lower = keys.Select(k => k.ToLower()).ToArray(); |
||||
|
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) //double->string
|
||||
|
{ |
||||
|
double _value = (double)value; |
||||
|
int pow_count = 0; |
||||
|
|
||||
|
while (_value >= 1000) |
||||
|
{ |
||||
|
_value = _value / 1000; |
||||
|
pow_count++; |
||||
|
} |
||||
|
|
||||
|
return _value.ToString() + " " + keys[pow_count]; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) //string->double
|
||||
|
{ |
||||
|
#region old_code
|
||||
|
|
||||
|
/*if (_value >= 500 * 1e9) |
||||
|
{ |
||||
|
result = _value / 1e9; |
||||
|
return (result.ToString() + " гГц"); |
||||
|
} |
||||
|
else if (_value >= 1e6 & _value < 500 * 1e9) |
||||
|
{ |
||||
|
result = _value / 1e6; |
||||
|
return (result.ToString() + " мГц"); |
||||
|
} |
||||
|
else if (_value >= 1e3 & _value < 1e6) |
||||
|
{ |
||||
|
result = _value / 1e3; |
||||
|
return (result.ToString(CultureInfo.InvariantCulture) + " кГц"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return (_value).ToString() + " Гц"; |
||||
|
}*/ |
||||
|
/*double result; |
||||
|
if (Double.TryParse(value.ToString(), System.Globalization.NumberStyles.Any, |
||||
|
culture, out result)) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
else if (Double.TryParse(value.ToString().Replace(" Гц", ""), System.Globalization.NumberStyles.Any, |
||||
|
culture, out result)) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
else if (Double.TryParse(value.ToString().Replace(" МГц", ""), System.Globalization.NumberStyles.Any, |
||||
|
culture, out result)) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
else if (Double.TryParse(value.ToString().Replace(" ГГц", ""), System.Globalization.NumberStyles.Any, |
||||
|
culture, out result)) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
else if (Double.TryParse(value.ToString().Replace(" КГц", ""), System.Globalization.NumberStyles.Any, |
||||
|
culture, out result)) |
||||
|
{ |
||||
|
return result; |
||||
|
}*/ |
||||
|
#endregion
|
||||
|
|
||||
|
string s = (string)value; |
||||
|
|
||||
|
Regex regex = new Regex(@"^\s*([0-9]+\.?[0-9]+)\s*([a-zA-Zа-яА-Я]+)?\s*$"); |
||||
|
if (!string.IsNullOrEmpty(s)) |
||||
|
{ |
||||
|
Match match = regex.Match(s); |
||||
|
|
||||
|
var groups = match.Success ? match.Groups : null; |
||||
|
|
||||
|
double savedValue = 0; |
||||
|
if (groups != null) |
||||
|
{ |
||||
|
Group doublePart = groups[1]; Group stringPart = groups[2]; |
||||
|
|
||||
|
int index = 0; |
||||
|
if (!string.IsNullOrEmpty(stringPart.Value)) |
||||
|
{ |
||||
|
if (keys.Contains(stringPart.Value.ToLower())) |
||||
|
index = Array.IndexOf(keys, stringPart.Value.ToLower()); |
||||
|
else |
||||
|
return 0; |
||||
|
} |
||||
|
savedValue = Math.Pow(1000, index) * System.Convert.ToDouble(doublePart.Value, CultureInfo.InvariantCulture); |
||||
|
savedValue = (savedValue > 500 * 1e9) ? 500 * 1e9 : savedValue; |
||||
|
return savedValue; |
||||
|
} |
||||
|
} |
||||
|
return value; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
<UserControl x:Class="SignalsMVVM.UserControl1" |
||||
|
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:SignalsMVVM" |
||||
|
mc:Ignorable="d" |
||||
|
d:DesignHeight="450" d:DesignWidth="800"> |
||||
|
<Grid> |
||||
|
|
||||
|
</Grid> |
||||
|
</UserControl> |
@ -0,0 +1,28 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Media.Imaging; |
||||
|
using System.Windows.Navigation; |
||||
|
using System.Windows.Shapes; |
||||
|
|
||||
|
namespace SignalsMVVM |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Interaction logic for UserControl1.xaml
|
||||
|
/// </summary>
|
||||
|
public partial class UserControl1 : UserControl |
||||
|
{ |
||||
|
public UserControl1() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<packages> |
||||
|
<package id="Autofac" version="4.8.1" targetFramework="net461" /> |
||||
|
<package id="Costura.Fody" version="3.2.0" targetFramework="net461" /> |
||||
|
<package id="Fody" version="3.3.2" targetFramework="net461" developmentDependency="true" /> |
||||
|
<package id="PropertyChanged.Fody" version="2.6.0" targetFramework="net461" /> |
||||
|
</packages> |
Loading…
Reference in new issue