Browse Source

Новая логика управления процедурой. Теперь главная модель реализует интерфейс ICommand.

master
Никита 6 years ago
parent
commit
2f821a3844
  1. 1
      Signal Generator/AddSignalWindow.xaml.cs
  2. 57
      Signal Generator/DrawTask.cs
  3. 5
      Signal Generator/MainWindow.xaml.cs
  4. 145
      Signal Generator/ProcedureModel.cs
  5. 2
      Signal Generator/Signal Generator.csproj
  6. 19
      Signal Generator/Signal/MultiSignal.cs
  7. 24
      Signal Generator/TaskViewConverter.cs
  8. 26
      Signal Generator/TaskWindow.xaml
  9. 40
      Signal Generator/TaskWindow.xaml.cs

1
Signal Generator/AddSignalWindow.xaml.cs

@ -22,6 +22,7 @@ namespace Signal_Generator
{
ObservableCollection<Parameter> signalProps = new ObservableCollection<Parameter>();
ObservableCollection<IAnalogSignal> typesOfSignal = new ObservableCollection<IAnalogSignal>();
public AddSignalWindow()
{
InitializeComponent();

57
Signal Generator/DrawTask.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
@ -12,31 +13,47 @@ using System.Windows.Shapes;
namespace Signal_Generator
{
public class DrawTask : Task
public class DrawTask : Task, INotifyPropertyChanged
{
Canvas currentCanvas;
Canvas canvas;
System.Timers.Timer taskTimer;
Stopwatch stopwatch = new Stopwatch();
MultiSignal currentMultiSignal;
public DStatus dStatus;
public enum DStatus
MultiSignal multiSignal;
private State _state;
public State state
{
get { return _state; }
set
{
_state = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("state"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public enum State
{
Created, Running, Paused, Finished, Canceled
}
public DrawTask(Action a) : base(a) { }
public void buildTask(MultiSignal s, Canvas c)
public void buildTask(Canvas c)
{
currentCanvas = c;
currentMultiSignal = s;
dStatus = DStatus.Running;
drawSignalAtCanvas();
canvas = c;
multiSignal = MultiSignal.getInstance();
state = State.Running;
stopwatch.Start();
taskTimer = new System.Timers.Timer(2000);
taskTimer.Elapsed += updateTextForms;
taskTimer.Enabled = true;
drawSignalAtCanvas();
}
private void updateTextForms(object sender, ElapsedEventArgs e)
{
@ -46,24 +63,24 @@ namespace Signal_Generator
private void drawSignalAtCanvas()
{
double lastX = 0, lastY = 0;
double w = currentCanvas.ActualWidth;
double w = canvas.ActualWidth;
for (int i = 0; i != (int)w; i++)
{
double y = currentMultiSignal.currentAmplitude(i / 5.0);
double y = multiSignal.currentAmplitude(i / 5.0);
drawLine(lastX, lastY, i, y);
lastX = i;
lastY = y;
Thread.Sleep(10);
switch (dStatus)
switch (state)
{
case DStatus.Paused:
while (dStatus == DStatus.Paused)
case State.Paused:
while (state == State.Paused)
Thread.Sleep(10);
break;
case DStatus.Canceled: return;
case State.Canceled: return;
}
}
dStatus = DStatus.Finished;
state = State.Finished;
}
private void drawLine(double x1, double y1, double x2, double y2)
@ -76,14 +93,14 @@ namespace Signal_Generator
l.Y1 = remap(y1);
l.X2 = x2;
l.Y2 = remap(y2);
currentCanvas.Children.Add(l);
canvas.Children.Add(l);
};
currentCanvas.Dispatcher.Invoke(a);
canvas.Dispatcher.Invoke(a);
}
private double remap(double x, double oldMin = -100.0, double oldMax = 100.0, double newMin = 100.0, double newMax = 0.0)
{
newMin = currentCanvas.ActualHeight;
newMin = canvas.ActualHeight;
return newMin + (x - oldMin) * (newMax - newMin) / (oldMax - oldMin);
}
}

5
Signal Generator/MainWindow.xaml.cs

@ -56,16 +56,15 @@ namespace Signal_Generator
addSignalWindow_Instance.Close();
}
private void startProcedure_Button_Click(object sender, RoutedEventArgs e)
{
IsEnabled = false;
MultiSignal ms = new MultiSignal();
MultiSignal ms = MultiSignal.getInstance();
foreach (IAnalogSignal item in signalCollection)
{
ms.add(item);
}
taskWindow_Instance = new TaskWindow(ms);
taskWindow_Instance = new TaskWindow();
taskWindow_Instance.Show();
taskWindow_Instance.Closed += enableMainWindow;
}

145
Signal Generator/ProcedureModel.cs

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Signal_Generator
{
public class ProcedureModel : ICommand
{
public DrawTask currentTask;
Canvas targetCanvas;
public ProcedureModel()
{
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, new EventArgs());
}
private void RaiseCanExecuteChanged(object o, PropertyChangedEventArgs e)
{
Action a = () =>
{
RaiseCanExecuteChanged();
};
targetCanvas.Dispatcher.Invoke(a);
}
public bool CanExecute(object parameter)
{
if (parameter == null) return false;
var parameters = parameter as object[];
var btn = parameters[0] as Button;
var ms = MultiSignal.getInstance();
if ((ms == null) && (ms.count() == 0))
return false;
switch (btn.Name)
{
case "start_Button":
btn.Content = updateStartButtonContent();
return true;
default:
btn.Content = updatePauseButtonContent().Item2;
if (!updatePauseButtonContent().Item1)
return false;
return true;
}
}
private string updateStartButtonContent()
{
if (currentTask == null) return "Запустить";
switch (currentTask.state)
{
case DrawTask.State.Created:
return "Запустить";
case DrawTask.State.Running:
return "Завершить";
case DrawTask.State.Paused:
goto case DrawTask.State.Running;
default:
goto case DrawTask.State.Created;
}
}
private Tuple<bool, string> updatePauseButtonContent()
{
if (currentTask == null) return new Tuple<bool, string>(false, "Пауза");
switch (currentTask.state)
{
case DrawTask.State.Created:
return new Tuple<bool, string>(false, "Пауза");
case DrawTask.State.Running:
return new Tuple<bool, string>(true, "Пауза");
case DrawTask.State.Paused:
return new Tuple<bool, string>(true, "Возобновить");
default:
goto case DrawTask.State.Created;
}
}
public void Execute(object parameter)
{
var parameters = parameter as object[];
var btn = parameters[0] as Button;
targetCanvas = parameters[1] as Canvas;
switch (btn.Name)
{
case "start_Button":
startOrCancelTask();
break;
case "pause_Button":
pauseOrResumeTask();
break;
}
}
private void startOrCancelTask ()
{
targetCanvas.Children.Clear();
if (currentTask != null)
switch (currentTask.state)
{
case DrawTask.State.Paused:
goto case DrawTask.State.Running;
case DrawTask.State.Running:
currentTask.state = DrawTask.State.Canceled;
return;
}
Action newAction = () =>
{
currentTask.PropertyChanged += RaiseCanExecuteChanged;
currentTask.buildTask(targetCanvas);
};
currentTask = new DrawTask(newAction);
currentTask.Start();
}
private void pauseOrResumeTask()
{
switch (currentTask.state)
{
case DrawTask.State.Paused:
currentTask.state = DrawTask.State.Running;
break;
case DrawTask.State.Running:
currentTask.state = DrawTask.State.Paused;
break;
}
}
}
}

2
Signal Generator/Signal Generator.csproj

@ -59,11 +59,13 @@
<DependentUpon>AddSignalWindow.xaml</DependentUpon>
</Compile>
<Compile Include="DrawTask.cs" />
<Compile Include="ProcedureModel.cs" />
<Compile Include="Signal\Base\AnalogSignalMethods.cs" />
<Compile Include="Signal\FmSignal.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Signal\Base\Parameter.cs" />
<Compile Include="Signal\SinusoidalSignal.cs" />
<Compile Include="TaskViewConverter.cs" />
<Compile Include="TaskWindow.xaml.cs">
<DependentUpon>TaskWindow.xaml</DependentUpon>
</Compile>

19
Signal Generator/Signal/MultiSignal.cs

@ -9,13 +9,21 @@ namespace Signal_Generator
{
public class MultiSignal : IAnalogSignal
{
private static MultiSignal instance;
private List<IAnalogSignal> signals { get; set; }
public MultiSignal()
private MultiSignal()
{
signals = new List<IAnalogSignal>();
}
public static MultiSignal getInstance()
{
if (instance == null)
instance = new MultiSignal();
return instance;
}
internal void add(IAnalogSignal signal)
{
signals.Add(signal);
@ -26,6 +34,11 @@ namespace Signal_Generator
signals.Remove(signal);
}
internal int count()
{
return signals.Count();
}
public double currentAmplitude(double t)
{
double summaryAmplitude = 0;
@ -39,13 +52,9 @@ namespace Signal_Generator
// Неиспользуемые поля и методы
public string typeToString => throw new NotImplementedException();
string IAnalogSignal.paramsToString => throw new NotImplementedException();
string IAnalogSignal.typeToString => throw new NotImplementedException();
Collection<Parameter> IAnalogSignal.paramsCollection { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
double IAnalogSignal.currentAmplitude(double t)
{
throw new NotImplementedException();

24
Signal Generator/TaskViewConverter.cs

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Data;
namespace Signal_Generator
{
class ArrayConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.Clone();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

26
Signal Generator/TaskWindow.xaml

@ -1,4 +1,5 @@
<Window x:Class="Signal_Generator.TaskWindow"
x:Name="TaskWindowView"
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"
@ -7,7 +8,12 @@
mc:Ignorable="d"
Title="Моделирование работы группы сигналов" Height="250" Width="500"
ResizeMode="NoResize">
<Grid Margin="10">
<Window.Resources>
<local:ProcedureModel x:Key="ProcedureModel"/>
<local:ArrayConverter x:Key="ArrayConverter"/>
</Window.Resources>
<Grid Margin="10" Loaded="Grid_Loaded">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
@ -27,8 +33,22 @@
<TextBlock x:Name="currentAmplitude_TextBlock" Margin="0,0,5,5" Grid.Row="2" Grid.Column="1">Текущий сигнал:</TextBlock>
<TextBox x:Name="currentAmplitude_TextBox" Margin="0,0,0,5" Grid.Row="2" Grid.Column="2"/>
<Button x:Name="start_Button" Width="120" Content="Запустить" Margin="5,0" Grid.Row="3" Grid.Column="0"
Grid.ColumnSpan="2" Click="start_Button_Click"/>
Grid.ColumnSpan="2" Command="{StaticResource ProcedureModel}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ArrayConverter}">
<Binding ElementName="start_Button"/>
<Binding ElementName="signalGraph_Canvas"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
<Button x:Name="pause_Button" Width="120" Content="Приостановить" Margin="5,0" Grid.Row="3" Grid.Column="2"
Grid.ColumnSpan="2" Click="pause_Button_Click"/>
Grid.ColumnSpan="2" Command="{StaticResource ProcedureModel}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ArrayConverter}">
<Binding ElementName="pause_Button"/>
<Binding ElementName="signalGraph_Canvas"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
</Grid>
</Window>

40
Signal Generator/TaskWindow.xaml.cs

@ -23,47 +23,15 @@ namespace Signal_Generator
public partial class TaskWindow : Window
{
MultiSignal currentMultiSignal;
DrawTask currentTask;
public TaskWindow(MultiSignal s)
public TaskWindow()
{
InitializeComponent();
currentMultiSignal = s;
}
private void start_Button_Click(object sender, RoutedEventArgs e)
{
signalGraph_Canvas.Children.Clear();
if (currentTask != null)
switch (currentTask.dStatus)
{
case DrawTask.DStatus.Paused:
goto case DrawTask.DStatus.Running;
case DrawTask.DStatus.Running:
currentTask.dStatus = DrawTask.DStatus.Canceled;
break;
}
Action newAction = () =>
{
currentTask.buildTask(currentMultiSignal, signalGraph_Canvas);
};
currentTask = new DrawTask(newAction);
currentTask.Start();
}
private void pause_Button_Click(object sender, RoutedEventArgs e)
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
switch (currentTask.dStatus) {
case DrawTask.DStatus.Paused:
currentTask.dStatus = DrawTask.DStatus.Running;
pause_Button.Content = "Приостановить";
break;
case DrawTask.DStatus.Running:
currentTask.dStatus = DrawTask.DStatus.Paused;
pause_Button.Content = "Возобновить";
break;
}
// принудительное обновление
((ProcedureModel)Resources["ProcedureModel"]).RaiseCanExecuteChanged();
}
}
}

Loading…
Cancel
Save