Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
20f4d61
Заготовка асинхронного сервиса данных
Infarh Jun 6, 2020
25ea254
Длительная операция вычисления значения в потоке UI
Infarh Jun 6, 2020
4c65384
Взаимодействие с визуальными элемнетами из вторичных потоков
Infarh Jun 6, 2020
3a83780
WinForms
Infarh Jun 6, 2020
20f4664
Устраняем проблему межпотокового взаимодействия в зародыше - в модели…
Infarh Jun 6, 2020
4d6c22e
Создание потоков
Infarh Jun 20, 2020
62f45bc
Передаём параметр в поток
Infarh Jun 20, 2020
863052a
Блокировка критической секции
Infarh Jun 20, 2020
5f0501c
Остановка потоков
Infarh Jun 20, 2020
520fb72
Блокировка потоков и их взаимная синхронизация
Infarh Jun 20, 2020
8ea5685
Заготовка Web-сервера
Infarh Jun 20, 2020
2eb90ad
Заготовка асинхронного сервера
Infarh Jun 20, 2020
cdbcd59
Базовая реализация WebServer'а
Infarh Jun 20, 2020
f0d7e3d
Тестирование работы Web-сервера
Infarh Jun 20, 2020
8654bab
Представление и модель-представления для Web-сервера
Infarh Jun 20, 2020
7fcccfb
Заготовка сервиса для web-сервера
Infarh Jun 20, 2020
57d723f
Доработка модели-представления для web-сервера
Infarh Jun 20, 2020
527fb8b
Простейшая логика отправки данных в браузер
Infarh Jun 20, 2020
e322b7a
Рассинхронизация процесса получения входящих подключений
Infarh Jun 20, 2020
5fba65f
Проверка возможности многопоточности сервера путём внесения 3-секундн…
Infarh Jun 20, 2020
3630446
Merge pull request #12 from Infarh/MultiThreading
Infarh Jun 20, 2020
2c513c6
Добавление триггера из пакета xaml/behaviors
Infarh Jun 27, 2020
4dc3933
Поведение, способное реагировать на события мыши для перетаскивания о…
Infarh Jun 27, 2020
57cef02
Поведение для кнопки - закрытие окна + свойства-зависимости в поведениях
Infarh Jun 27, 2020
6c7b106
Добавление тестового окна для отработки стиля
Infarh Jun 27, 2020
b6457f3
Заготовка для стиля окна
Infarh Jun 27, 2020
f9e9344
Заготовка шаблона окна
Infarh Jun 27, 2020
47b73a5
Отображение иконки в заголовке окна
Infarh Jun 27, 2020
2ba2238
Геометрия и внешний вид системных кнопок в окне
Infarh Jun 27, 2020
60fad65
Методы-расширения для DependencyObject, позволяющие найти его корень …
Infarh Jun 27, 2020
728d41a
Добавлены поведения для системных кнопок окна
Infarh Jun 27, 2020
38ca183
Методы-расширения для поиска элемента среди родительских в визуальном…
Infarh Jun 27, 2020
32802fc
Обеспечиваем возможность перетаскивания окна за заголовок
Infarh Jun 27, 2020
edd604d
Зазвёртывание окна на весь экран по двойному щелчку мыши в заголовке
Infarh Jun 27, 2020
56636b5
Системное меню в иконке в левом верхнем углу окна
Infarh Jun 27, 2020
6c668f7
Добавляем логику масштабирования кона
Infarh Jun 27, 2020
8e3f51e
Иконка и стиль для главного окна
Infarh Jun 27, 2020
63bfc48
Merge pull request #13 from Infarh/Interactivity
Infarh Jun 27, 2020
f03ccfc
Рефакторинг
Infarh Jul 11, 2020
1c9d784
Репозиторий студентов и групп
Infarh Jul 11, 2020
ef96d49
Макет представления окна управлени управления студентами
Infarh Jul 11, 2020
4982787
Команда открытия окна управления студентами
Infarh Jul 11, 2020
b9f7154
Рефакторинг
Infarh Jul 11, 2020
ff62573
Менеджер студентов (UnitOfWork)
Infarh Jul 11, 2020
eec9988
Тестовые данные
Infarh Jul 11, 2020
e30ad39
Отображение студентов
Infarh Jul 11, 2020
549317e
Кнопки для редактирования студентов
Infarh Jul 11, 2020
7559c21
Отображение информации о выбранном студенте
Infarh Jul 11, 2020
f92abe5
Заготовки команд редактирования и создания Студента
Infarh Jul 11, 2020
0e42620
Окно диалога редактирования студента
Infarh Jul 11, 2020
8d7dc17
Сервис диалога с пользвоателем по средствам модальных окон
Infarh Jul 11, 2020
a70dc85
Диалог с пользвоателем для запроса текстовых данных
Infarh Jul 11, 2020
be3ecc1
Merge pull request #14 from Infarh/MVVMEditors
Infarh Jul 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CV19.Web/CV19.Web.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

</Project>
80 changes: 80 additions & 0 deletions CV19.Web/WebServer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Net;
using System.Threading.Tasks;

namespace CV19.Web
{
public class WebServer
{
public event EventHandler<RequestReceiverEventArgs> RequestReceived;

//private TcpListener _Listener = new TcpListener(new IPEndPoint(IPAddress.Any, 8080));
private HttpListener _Listener;
private readonly int _Port;
private bool _Enabled;
private readonly object _SyncRoot = new object();

public int Port => _Port;

public bool Enabled { get => _Enabled; set { if (value) Start(); else Stop(); } }

public WebServer(int Port) => _Port = Port;

public void Start()
{
if (_Enabled) return;
lock (_SyncRoot)
{
if (_Enabled) return;

_Listener = new HttpListener();
_Listener.Prefixes.Add($"http://*:{_Port}/"); // netsh http add urlacl url=http://*:8080/ user=user_name
_Listener.Prefixes.Add($"http://+:{_Port}/");
_Enabled = true;
ListenAsync();
}
}

public void Stop()
{
if (!_Enabled) return;
lock (_SyncRoot)
{
if (!_Enabled) return;

_Listener = null;
_Enabled = false;
}
}

private async void ListenAsync()
{
var listener = _Listener;

listener.Start();

HttpListenerContext context = null;
while (_Enabled)
{
var get_context_task = listener.GetContextAsync();
if (context != null)
ProcessRequestAsync(context);
context = await get_context_task.ConfigureAwait(false);
}

listener.Stop();
}

private async void ProcessRequestAsync(HttpListenerContext context)
{
await Task.Run(() => RequestReceived?.Invoke(this, new RequestReceiverEventArgs(context)));
}
}

public class RequestReceiverEventArgs : EventArgs
{
public HttpListenerContext Context { get; }

public RequestReceiverEventArgs(HttpListenerContext context) => Context = context;
}
}
19 changes: 16 additions & 3 deletions CV19.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30104.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CV19", "CV19\CV19.csproj", "{FC92495F-1218-49A6-B295-E2EC2FEE3A67}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CV19", "CV19\CV19.csproj", "{FC92495F-1218-49A6-B295-E2EC2FEE3A67}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E4416DE8-06BF-433C-A992-1FD7803895E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CV19Console", "Tests\CV19Console\CV19Console.csproj", "{6C8C5A2C-B181-49C3-A218-1150B0635A3A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CV19Console", "Tests\CV19Console\CV19Console.csproj", "{6C8C5A2C-B181-49C3-A218-1150B0635A3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CV19WPFTest", "Tests\CV19WPFTest\CV19WPFTest.csproj", "{16133638-8F17-4B64-9815-7E6178544A1C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CV19WPFTest", "Tests\CV19WPFTest\CV19WPFTest.csproj", "{16133638-8F17-4B64-9815-7E6178544A1C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CV19WinFormsTest", "Tests\CV19WinFormsTest\CV19WinFormsTest.csproj", "{8EB32BD1-1FAD-4FE5-BA31-D974CD1CAF9D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CV19.Web", "CV19.Web\CV19.Web.csproj", "{16558D4A-3611-4D65-B6ED-97ED75DBCAC7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -29,13 +33,22 @@ Global
{16133638-8F17-4B64-9815-7E6178544A1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16133638-8F17-4B64-9815-7E6178544A1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16133638-8F17-4B64-9815-7E6178544A1C}.Release|Any CPU.Build.0 = Release|Any CPU
{8EB32BD1-1FAD-4FE5-BA31-D974CD1CAF9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EB32BD1-1FAD-4FE5-BA31-D974CD1CAF9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EB32BD1-1FAD-4FE5-BA31-D974CD1CAF9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EB32BD1-1FAD-4FE5-BA31-D974CD1CAF9D}.Release|Any CPU.Build.0 = Release|Any CPU
{16558D4A-3611-4D65-B6ED-97ED75DBCAC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16558D4A-3611-4D65-B6ED-97ED75DBCAC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16558D4A-3611-4D65-B6ED-97ED75DBCAC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16558D4A-3611-4D65-B6ED-97ED75DBCAC7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6C8C5A2C-B181-49C3-A218-1150B0635A3A} = {E4416DE8-06BF-433C-A992-1FD7803895E3}
{16133638-8F17-4B64-9815-7E6178544A1C} = {E4416DE8-06BF-433C-A992-1FD7803895E3}
{8EB32BD1-1FAD-4FE5-BA31-D974CD1CAF9D} = {E4416DE8-06BF-433C-A992-1FD7803895E3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9234878E-A7A4-4B01-BBF9-00E7090A01BA}
Expand Down
1 change: 1 addition & 0 deletions CV19/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<ResourceDictionary Source="Resources/Styles/Buttons.xaml"/>
<ResourceDictionary Source="Resources/Styles/GridSplitters.xaml"/>
<ResourceDictionary Source="Resources/Styles/CV19WindowStyle.xaml"/>

</ResourceDictionary.MergedDictionaries>

Expand Down
12 changes: 3 additions & 9 deletions CV19/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,9 @@ protected override async void OnExit(ExitEventArgs e)
__Host = null;
}

public static void ConfigureServices(HostBuilderContext host, IServiceCollection services)
{
services.AddSingleton<IDataService, DataService>();
//services.AddTransient<IDataService, DataService>();
//services.AddScoped<IDataService, DataService>();

services.AddSingleton<MainWindowViewModel>();
services.AddSingleton<CountriesStatisticViewModel>();
}
public static void ConfigureServices(HostBuilderContext host, IServiceCollection services) => services
.RegisterServices()
.RegisterViewModels();

public static string CurrentDirectory => IsDesignMode
? Path.GetDirectoryName(GetSourceCodePath())
Expand Down
18 changes: 16 additions & 2 deletions CV19/CV19.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,26 @@
<Page Remove="Data\**" />
</ItemGroup>

<ItemGroup>
<None Remove="Resources\WindowIcon.ico" />
<None Remove="Resources\WindowIcon.png" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FontAwesome5" Version="2.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.5" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="OxyPlot.Wpf" Version="2.0.0" />
<PackageReference Include="XAML.MapControl" Version="5.2.1" />
<PackageReference Include="XAML.MapControl" Version="5.3.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CV19.Web\CV19.Web.csproj" />
</ItemGroup>

<ItemGroup>
<Resource Include="Resources\WindowIcon.ico" />
<Resource Include="Resources\WindowIcon.png" />
</ItemGroup>

<ItemGroup>
Expand Down
17 changes: 17 additions & 0 deletions CV19/Infrastructure/Behaviors/CloseWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Xaml.Behaviors;

namespace CV19.Infrastructure.Behaviors
{
class CloseWindow : Behavior<Button>
{
protected override void OnAttached() => AssociatedObject.Click += OnButtonClick;

protected override void OnDetaching() => AssociatedObject.Click -= OnButtonClick;

private void OnButtonClick(object Sender, RoutedEventArgs E) =>
(AssociatedObject.FindVisualRoot() as Window)?.Close();
}
}
20 changes: 20 additions & 0 deletions CV19/Infrastructure/Behaviors/MinimizeWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Windows;
using System.Windows.Controls;
using Microsoft.Xaml.Behaviors;

namespace CV19.Infrastructure.Behaviors
{
class MinimizeWindow : Behavior<Button>
{
protected override void OnAttached() => AssociatedObject.Click += OnButtonClick;

protected override void OnDetaching() => AssociatedObject.Click -= OnButtonClick;

private void OnButtonClick(object Sender, RoutedEventArgs E)
{
if (!(AssociatedObject.FindVisualRoot() is Window window)) return;

window.WindowState = WindowState.Minimized;
}
}
}
92 changes: 92 additions & 0 deletions CV19/Infrastructure/Behaviors/ResizeWindowPanel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Shapes;
using CV19.Infrastructure.Extensions;
using Microsoft.Xaml.Behaviors;

namespace CV19.Infrastructure.Behaviors
{
class ResizeWindowPanel : Behavior<Panel>
{
protected override void OnAttached() => AssociatedObject.MouseLeftButtonDown += OnMouseDown;

protected override void OnDetaching() => AssociatedObject.MouseLeftButtonDown -= OnMouseDown;

private void OnMouseDown(object Sender, MouseButtonEventArgs E)
{
if (!(AssociatedObject.FindVisualRoot() is Window window)) return;

switch (E.OriginalSource)
{
default: return;
case Line line:
ResizeLine(line, window);
break;

case Rectangle rect:
ResizeRect(rect, window);
break;
}
}

public enum SizingAction
{
West = 1,
East = 2,
North = 3,
NorthWest = 4,
NorthEast = 5,
South = 6,
SouthWest = 7,
SouthEast = 8,
}

private static void ResizeLine(Line line, Window window)
{
switch (line.VerticalAlignment)
{
case VerticalAlignment.Top:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.North), IntPtr.Zero);
break;

case VerticalAlignment.Bottom:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.South), IntPtr.Zero);
break;

default:
switch (line.HorizontalAlignment)
{
case HorizontalAlignment.Left:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.West), IntPtr.Zero);
break;

case HorizontalAlignment.Right:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.East), IntPtr.Zero);
break;
}
break;
}
}

private static void ResizeRect(Rectangle rect, Window window)
{
switch (rect.VerticalAlignment)
{
case VerticalAlignment.Top when rect.HorizontalAlignment == HorizontalAlignment.Left:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.NorthWest), IntPtr.Zero);
break;
case VerticalAlignment.Top when rect.HorizontalAlignment == HorizontalAlignment.Right:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.NorthEast), IntPtr.Zero);
break;
case VerticalAlignment.Bottom when rect.HorizontalAlignment == HorizontalAlignment.Left:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.SouthWest), IntPtr.Zero);
break;
case VerticalAlignment.Bottom when rect.HorizontalAlignment == HorizontalAlignment.Right:
window.SendMessage(WM.SYSCOMMAND, (IntPtr)((int)SC.SIZE + SizingAction.SouthEast), IntPtr.Zero);
break;
}
}
}
}
35 changes: 35 additions & 0 deletions CV19/Infrastructure/Behaviors/WindowStateChange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Windows;
using System.Windows.Controls;
using Microsoft.Xaml.Behaviors;

namespace CV19.Infrastructure.Behaviors
{
class WindowStateChange : Behavior<Button>
{
protected override void OnAttached() => AssociatedObject.Click += OnButtonClick;

protected override void OnDetaching() => AssociatedObject.Click -= OnButtonClick;

private void OnButtonClick(object Sender, RoutedEventArgs E)
{
if (!(AssociatedObject.FindVisualRoot() is Window window)) return;

//switch (window.WindowState)
//{
// case WindowState.Normal:
// window.WindowState = WindowState.Maximized;
// break;
// case WindowState.Maximized:
// window.WindowState = WindowState.Normal;
// break;
//}

window.WindowState = window.WindowState switch
{
WindowState.Normal => WindowState.Maximized,
WindowState.Maximized => WindowState.Normal,
_ => window.WindowState
};
}
}
}
36 changes: 36 additions & 0 deletions CV19/Infrastructure/Behaviors/WindowSystemIconBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using CV19.Infrastructure.Extensions;
using Microsoft.Xaml.Behaviors;

namespace CV19.Infrastructure.Behaviors
{
class WindowSystemIconBehavior : Behavior<Image>
{
protected override void OnAttached()
{
AssociatedObject.MouseLeftButtonDown += OnMouseDown;
}

protected override void OnDetaching()
{
AssociatedObject.MouseLeftButtonDown -= OnMouseDown;
}

private void OnMouseDown(object Sender, MouseButtonEventArgs E)
{
if (!(AssociatedObject.FindVisualRoot() is Window window)) return;

E.Handled = true;

if(E.ClickCount > 1)
window.Close();
else
window.SendMessage(WM.SYSCOMMAND, SC.KEYMENU);
}
}
}
Loading