添加项目文件。
This commit is contained in:
parent
d9c9687a8b
commit
925dc6155d
67
linesider_screen_bankend.sln
Normal file
67
linesider_screen_bankend.sln
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35919.96 d17.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linesider_screen_bankend.Modules.ModuleName.Tests", "linesider_screen_bankend\Tests\linesider_screen_bankend.Modules.ModuleName.Tests\linesider_screen_bankend.Modules.ModuleName.Tests.csproj", "{35E456EA-B00D-836A-01DD-847FD5160483}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{C9AD4566-5B66-40D2-B6C0-7CE2C1434FFA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linesider_screen_bankend.Modules.ModuleName", "linesider_screen_bankend\Modules\linesider_screen_bankend.Modules.ModuleName\linesider_screen_bankend.Modules.ModuleName.csproj", "{D6FC7446-D621-6607-8B56-DBFF09E12B6D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{FD560FA8-19E9-42DF-AFAC-D8D439F16916}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linesider_screen_bankend.Services", "linesider_screen_bankend\Services\linesider_screen_bankend.Services\linesider_screen_bankend.Services.csproj", "{D9EC6920-FC64-BE4A-ECC0-BFD93DA3FEC1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linesider_screen_bankend.Services.Interfaces", "linesider_screen_bankend\Services\linesider_screen_bankend.Services.Interfaces\linesider_screen_bankend.Services.Interfaces.csproj", "{2D870641-D0E0-20A4-F37D-15DA8673ABCB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linesider_screen_bankend", "linesider_screen_bankend\linesider_screen_bankend\linesider_screen_bankend.csproj", "{2CA9B9D5-2DC8-260D-0931-3AA8F065172C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linesider_screen_bankend.Core", "linesider_screen_bankend\linesider_screen_bankend.Core\linesider_screen_bankend.Core.csproj", "{3153BFCD-9C29-CFC5-A014-A425BB1CF856}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{35E456EA-B00D-836A-01DD-847FD5160483}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{35E456EA-B00D-836A-01DD-847FD5160483}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{35E456EA-B00D-836A-01DD-847FD5160483}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{35E456EA-B00D-836A-01DD-847FD5160483}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6FC7446-D621-6607-8B56-DBFF09E12B6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6FC7446-D621-6607-8B56-DBFF09E12B6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6FC7446-D621-6607-8B56-DBFF09E12B6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6FC7446-D621-6607-8B56-DBFF09E12B6D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9EC6920-FC64-BE4A-ECC0-BFD93DA3FEC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D9EC6920-FC64-BE4A-ECC0-BFD93DA3FEC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D9EC6920-FC64-BE4A-ECC0-BFD93DA3FEC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9EC6920-FC64-BE4A-ECC0-BFD93DA3FEC1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2D870641-D0E0-20A4-F37D-15DA8673ABCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2D870641-D0E0-20A4-F37D-15DA8673ABCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2D870641-D0E0-20A4-F37D-15DA8673ABCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2D870641-D0E0-20A4-F37D-15DA8673ABCB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2CA9B9D5-2DC8-260D-0931-3AA8F065172C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2CA9B9D5-2DC8-260D-0931-3AA8F065172C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2CA9B9D5-2DC8-260D-0931-3AA8F065172C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2CA9B9D5-2DC8-260D-0931-3AA8F065172C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3153BFCD-9C29-CFC5-A014-A425BB1CF856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3153BFCD-9C29-CFC5-A014-A425BB1CF856}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3153BFCD-9C29-CFC5-A014-A425BB1CF856}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3153BFCD-9C29-CFC5-A014-A425BB1CF856}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{35E456EA-B00D-836A-01DD-847FD5160483} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{D6FC7446-D621-6607-8B56-DBFF09E12B6D} = {C9AD4566-5B66-40D2-B6C0-7CE2C1434FFA}
|
||||
{D9EC6920-FC64-BE4A-ECC0-BFD93DA3FEC1} = {FD560FA8-19E9-42DF-AFAC-D8D439F16916}
|
||||
{2D870641-D0E0-20A4-F37D-15DA8673ABCB} = {FD560FA8-19E9-42DF-AFAC-D8D439F16916}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {83A42B0B-1337-4726-94BF-622DD10C68BD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@ -0,0 +1,28 @@
|
||||
using linesider_screen_bankend.Core;
|
||||
using linesider_screen_bankend.Modules.ModuleName.Views;
|
||||
using Prism.Ioc;
|
||||
using Prism.Modularity;
|
||||
using Prism.Regions;
|
||||
|
||||
namespace linesider_screen_bankend.Modules.ModuleName
|
||||
{
|
||||
public class ModuleNameModule : IModule
|
||||
{
|
||||
private readonly IRegionManager _regionManager;
|
||||
|
||||
public ModuleNameModule(IRegionManager regionManager)
|
||||
{
|
||||
_regionManager = regionManager;
|
||||
}
|
||||
|
||||
public void OnInitialized(IContainerProvider containerProvider)
|
||||
{
|
||||
_regionManager.RequestNavigate(RegionNames.ContentRegion, "ViewA");
|
||||
}
|
||||
|
||||
public void RegisterTypes(IContainerRegistry containerRegistry)
|
||||
{
|
||||
containerRegistry.RegisterForNavigation<ViewA>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
using linesider_screen_bankend.Core.Mvvm;
|
||||
using linesider_screen_bankend.Services.Interfaces;
|
||||
using Prism.Regions;
|
||||
|
||||
namespace linesider_screen_bankend.Modules.ModuleName.ViewModels
|
||||
{
|
||||
public class ViewAViewModel : RegionViewModelBase
|
||||
{
|
||||
private string _message;
|
||||
public string Message
|
||||
{
|
||||
get { return _message; }
|
||||
set { SetProperty(ref _message, value); }
|
||||
}
|
||||
|
||||
public ViewAViewModel(IRegionManager regionManager, IMessageService messageService) :
|
||||
base(regionManager)
|
||||
{
|
||||
Message = messageService.GetMessage();
|
||||
}
|
||||
|
||||
public override void OnNavigatedTo(NavigationContext navigationContext)
|
||||
{
|
||||
//do something
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
<UserControl x:Class="linesider_screen_bankend.Modules.ModuleName.Views.ViewA"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:linesider_screen_bankend.Modules.ModuleName.Views"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True" >
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding Message}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="24"/>
|
||||
</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 linesider_screen_bankend.Modules.ModuleName.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ViewA.xaml
|
||||
/// </summary>
|
||||
public partial class ViewA : UserControl
|
||||
{
|
||||
public ViewA()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Prism.Wpf" Version="8.1.97" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\linesider_screen_bankend.Core\linesider_screen_bankend.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Services\linesider_screen_bankend.Services.Interfaces\linesider_screen_bankend.Services.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,7 @@
|
||||
namespace linesider_screen_bankend.Services.Interfaces
|
||||
{
|
||||
public interface IMessageService
|
||||
{
|
||||
string GetMessage();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,12 @@
|
||||
using linesider_screen_bankend.Services.Interfaces;
|
||||
|
||||
namespace linesider_screen_bankend.Services
|
||||
{
|
||||
public class MessageService : IMessageService
|
||||
{
|
||||
public string GetMessage()
|
||||
{
|
||||
return "Hello from the Message Service";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\linesider_screen_bankend.Services.Interfaces\linesider_screen_bankend.Services.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,41 @@
|
||||
using linesider_screen_bankend.Modules.ModuleName.ViewModels;
|
||||
using linesider_screen_bankend.Services.Interfaces;
|
||||
using Moq;
|
||||
using Prism.Regions;
|
||||
using Xunit;
|
||||
|
||||
namespace linesider_screen_bankend.Modules.ModuleName.Tests.ViewModels
|
||||
{
|
||||
public class ViewAViewModelFixture
|
||||
{
|
||||
Mock<IMessageService> _messageServiceMock;
|
||||
Mock<IRegionManager> _regionManagerMock;
|
||||
const string MessageServiceDefaultMessage = "Some Value";
|
||||
|
||||
public ViewAViewModelFixture()
|
||||
{
|
||||
var messageService = new Mock<IMessageService>();
|
||||
messageService.Setup(x => x.GetMessage()).Returns(MessageServiceDefaultMessage);
|
||||
_messageServiceMock = messageService;
|
||||
|
||||
_regionManagerMock = new Mock<IRegionManager>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MessagePropertyValueUpdated()
|
||||
{
|
||||
var vm = new ViewAViewModel(_regionManagerMock.Object, _messageServiceMock.Object);
|
||||
|
||||
_messageServiceMock.Verify(x => x.GetMessage(), Times.Once);
|
||||
|
||||
Assert.Equal(MessageServiceDefaultMessage, vm.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MessageINotifyPropertyChangedCalled()
|
||||
{
|
||||
var vm = new ViewAViewModel(_regionManagerMock.Object, _messageServiceMock.Object);
|
||||
Assert.PropertyChanged(vm, nameof(vm.Message), () => vm.Message = "Changed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="Moq" Version="4.17.2" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Modules\linesider_screen_bankend.Modules.ModuleName\linesider_screen_bankend.Modules.ModuleName.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Prism.Regions;
|
||||
|
||||
namespace linesider_screen_bankend.Core.Mvvm
|
||||
{
|
||||
public class RegionViewModelBase : ViewModelBase, INavigationAware, IConfirmNavigationRequest
|
||||
{
|
||||
protected IRegionManager RegionManager { get; private set; }
|
||||
|
||||
public RegionViewModelBase(IRegionManager regionManager)
|
||||
{
|
||||
RegionManager = regionManager;
|
||||
}
|
||||
|
||||
public virtual void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
|
||||
{
|
||||
continuationCallback(true);
|
||||
}
|
||||
|
||||
public virtual bool IsNavigationTarget(NavigationContext navigationContext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnNavigatedFrom(NavigationContext navigationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnNavigatedTo(NavigationContext navigationContext)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
using Prism.Mvvm;
|
||||
using Prism.Navigation;
|
||||
|
||||
namespace linesider_screen_bankend.Core.Mvvm
|
||||
{
|
||||
public abstract class ViewModelBase : BindableBase, IDestructible
|
||||
{
|
||||
protected ViewModelBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
namespace linesider_screen_bankend.Core
|
||||
{
|
||||
public static class RegionNames
|
||||
{
|
||||
public const string ContentRegion = "ContentRegion";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using BarTender;
|
||||
|
||||
namespace linesider_screen_bankend.Core.Tools
|
||||
{
|
||||
public class BartenderPrintHelper : IDisposable
|
||||
{
|
||||
private Application _btApp;
|
||||
private Format _btFormat;
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 Bartender 应用程序
|
||||
/// </summary>
|
||||
public BartenderPrintHelper()
|
||||
{
|
||||
try
|
||||
{
|
||||
_btApp = new Application();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("无法初始化 Bartender 应用程序。请确保 BarTender 已安装。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打印标签
|
||||
/// </summary>
|
||||
/// <param name="templatePath">标签模板路径</param>
|
||||
/// <param name="subStringValues">标签变量键值对</param>
|
||||
/// <param name="copies">打印份数</param>
|
||||
/// <param name="serializedLabels">序列化标签数量</param>
|
||||
/// <returns>是否打印成功</returns>
|
||||
public bool PrintLabel(string templatePath, System.Collections.Generic.Dictionary<string, string> subStringValues, int copies = 1, int serializedLabels = 1)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("BartenderPrintHelper", "对象已被释放,不能执行打印操作。");
|
||||
|
||||
try
|
||||
{
|
||||
// 打开标签模板
|
||||
_btFormat = _btApp.Formats.Open(templatePath);
|
||||
|
||||
// 设置打印参数
|
||||
_btFormat.PrintSetup.IdenticalCopiesOfLabel = copies;
|
||||
_btFormat.PrintSetup.NumberSerializedLabels = serializedLabels;
|
||||
|
||||
// 设置标签变量值
|
||||
if (subStringValues != null)
|
||||
{
|
||||
foreach (var item in subStringValues)
|
||||
{
|
||||
_btFormat.SetNamedSubStringValue(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行打印
|
||||
_btFormat.PrintOut(false, false);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"打印标签时出错: {ex.Message}", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_btFormat != null)
|
||||
{
|
||||
_btFormat.Close(BtSaveOptions.btDoNotSaveChanges);
|
||||
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btFormat);
|
||||
_btFormat = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// 清理托管资源
|
||||
}
|
||||
|
||||
// 清理非托管资源
|
||||
if (_btFormat != null)
|
||||
{
|
||||
_btFormat.Close(BtSaveOptions.btDoNotSaveChanges);
|
||||
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btFormat);
|
||||
_btFormat = null;
|
||||
}
|
||||
|
||||
if (_btApp != null)
|
||||
{
|
||||
_btApp.Quit(BtSaveOptions.btDoNotSaveChanges);
|
||||
System.Runtime.InteropServices.Marshal.ReleaseComObject(_btApp);
|
||||
_btApp = null;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~BartenderPrintHelper()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="BarTender">
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<VersionMajor>11</VersionMajor>
|
||||
<Guid>d58562c1-e51b-11cf-8941-00a024a9083f</Guid>
|
||||
<Lcid>0</Lcid>
|
||||
<Isolated>false</Isolated>
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Prism.Wpf" Version="8.1.97" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,9 @@
|
||||
<prism:PrismApplication x:Class="linesider_screen_bankend.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:linesider_screen_bankend"
|
||||
xmlns:prism="http://prismlibrary.com/" >
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</prism:PrismApplication>
|
||||
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using EmbedIO;
|
||||
using EmbedIO.WebApi;
|
||||
using linesider_screen_bankend.Modules.ModuleName;
|
||||
using linesider_screen_bankend.Services;
|
||||
using linesider_screen_bankend.Services.Interfaces;
|
||||
using linesider_screen_bankend.Views;
|
||||
using Prism.Ioc;
|
||||
using Prism.Modularity;
|
||||
using linesider_screen_bankend.Controller;
|
||||
|
||||
namespace linesider_screen_bankend
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App
|
||||
{
|
||||
protected override Window CreateShell()
|
||||
{
|
||||
return Container.Resolve<MainWindow>();
|
||||
}
|
||||
|
||||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||
{
|
||||
containerRegistry.RegisterSingleton<IMessageService, MessageService>();
|
||||
}
|
||||
|
||||
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
|
||||
{
|
||||
moduleCatalog.AddModule<ModuleNameModule>();
|
||||
}
|
||||
|
||||
private CancellationTokenSource _cts;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
// 启动Web服务器
|
||||
//StartWebServer();
|
||||
}
|
||||
|
||||
//private void StartWebServer()
|
||||
//{
|
||||
// _cts = new CancellationTokenSource();
|
||||
|
||||
// var url = "http://localhost:9696/";
|
||||
|
||||
// // 在新线程中运行服务器,避免阻塞UI线程
|
||||
// var serverThread = new Thread(() =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// using (var server = CreateWebServer(url))
|
||||
// {
|
||||
// server.RunAsync(_cts.Token).Wait();
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// // 处理异常
|
||||
// MessageBox.Show($"Web服务器错误: {ex.Message}");
|
||||
// }
|
||||
// })
|
||||
// {
|
||||
// IsBackground = true
|
||||
// };
|
||||
|
||||
// serverThread.Start();
|
||||
//}
|
||||
|
||||
//private WebServer CreateWebServer(string url)
|
||||
//{
|
||||
// var server = new WebServer(o => o
|
||||
// .WithUrlPrefix(url)
|
||||
// .WithMode(HttpListenerMode.EmbedIO))
|
||||
// .WithWebApi("/api", m => m
|
||||
// .WithController<MyApiController>());
|
||||
|
||||
// return server;
|
||||
//}
|
||||
|
||||
//protected override void OnExit(ExitEventArgs e)
|
||||
//{
|
||||
// // 应用程序退出时停止服务器
|
||||
// _cts?.Cancel();
|
||||
// base.OnExit(e);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
using EmbedIO.Routing;
|
||||
using EmbedIO.WebApi;
|
||||
using EmbedIO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace linesider_screen_bankend.Controller
|
||||
{
|
||||
public class MyApiController : WebApiController
|
||||
{
|
||||
private readonly Action<string> _logAction;
|
||||
|
||||
public MyApiController(Action<string> logAction)
|
||||
{
|
||||
_logAction = logAction;
|
||||
}
|
||||
|
||||
[Route(HttpVerbs.Get, "/hello")]
|
||||
public string GetHello()
|
||||
{
|
||||
_logAction?.Invoke($"GET /api/hello from {HttpContext.RemoteEndPoint}");
|
||||
return "Hello from WPF!";
|
||||
}
|
||||
|
||||
[Route(HttpVerbs.Post, "/data")]
|
||||
public async Task<string> PostData()
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await HttpContext.GetRequestDataAsync<MyDataModel>();
|
||||
_logAction?.Invoke($"POST /api/data from {HttpContext.RemoteEndPoint}: {data}");
|
||||
return $"Received: Name={data.Name}, Value={data.Value}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logAction?.Invoke($"Error in POST /api/data: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyDataModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Value { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Name: {Name}, Value: {Value}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
using EmbedIO.Routing;
|
||||
using EmbedIO.WebApi;
|
||||
using EmbedIO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace linesider_screen_bankend.Controller
|
||||
{
|
||||
public class PrintCommunicationController: WebApiController
|
||||
{
|
||||
private readonly Action<string> _logAction;
|
||||
|
||||
public PrintCommunicationController(Action<string> logAction)
|
||||
{
|
||||
_logAction = logAction;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Route(HttpVerbs.Get, "/hello")]
|
||||
public string GetHello()
|
||||
{
|
||||
_logAction?.Invoke($"GET /api/hello from {HttpContext.RemoteEndPoint}");
|
||||
return "Hello from WPF!";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace linesider_screen_bankend.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : BindableBase
|
||||
{
|
||||
private string _title = "Prism Application";
|
||||
public string Title
|
||||
{
|
||||
get { return _title; }
|
||||
set { SetProperty(ref _title, value); }
|
||||
}
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
<Window x:Class="linesider_screen_bankend.Views.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
xmlns:core="clr-namespace:linesider_screen_bankend.Core;assembly=linesider_screen_bankend.Core"
|
||||
Title="{Binding Title}" Height="350" Width="525" >
|
||||
<Grid>
|
||||
<!--<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ContentRegion}" />-->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10">
|
||||
<TextBlock Text="EmbedIO Server URL:" VerticalAlignment="Center"/>
|
||||
<TextBox x:Name="UrlTextBox" Text="http://localhost:9696/" Width="200" Margin="10,0"/>
|
||||
<Button x:Name="StartButton" Content="Start Server" Click="StartButton_Click" Width="100" Margin="5,0"/>
|
||||
<Button x:Name="StopButton" Content="Stop Server" Click="StopButton_Click" Width="100" Margin="5,0" IsEnabled="False"/>
|
||||
</StackPanel>
|
||||
|
||||
<GroupBox Grid.Row="1" Header="HTTP Request Log" Margin="10">
|
||||
<Grid>
|
||||
<TextBox x:Name="LogTextBox" IsReadOnly="True"
|
||||
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
|
||||
FontFamily="Consolas" FontSize="12" TextWrapping="NoWrap"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</Window>
|
||||
@ -0,0 +1,138 @@
|
||||
using EmbedIO;
|
||||
using EmbedIO.WebApi;
|
||||
using linesider_screen_bankend.Controller;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
|
||||
|
||||
namespace linesider_screen_bankend.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private WebServer _server;
|
||||
private CancellationTokenSource _cts;
|
||||
private readonly ConcurrentQueue<string> _logQueue = new();
|
||||
private readonly DispatcherTimer _logTimer = new();
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
// 设置日志定时器,每100毫秒处理一次日志队列
|
||||
_logTimer.Interval = TimeSpan.FromMilliseconds(100);
|
||||
_logTimer.Tick += ProcessLogQueue;
|
||||
_logTimer.Start();
|
||||
|
||||
}
|
||||
private void StartButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_cts = new CancellationTokenSource();
|
||||
var url = UrlTextBox.Text.Trim();
|
||||
|
||||
_server = CreateWebServer(url);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
AddLog($"Starting server at {url}");
|
||||
_server.RunAsync(_cts.Token).Wait();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddLog($"Server error: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
StartButton.IsEnabled = true;
|
||||
StopButton.IsEnabled = false;
|
||||
});
|
||||
AddLog("Server stopped");
|
||||
}
|
||||
});
|
||||
|
||||
StartButton.IsEnabled = false;
|
||||
StopButton.IsEnabled = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddLog($"Failed to start server: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void StopButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_cts?.Cancel();
|
||||
StartButton.IsEnabled = true;
|
||||
StopButton.IsEnabled = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddLog($"Error stopping server: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private WebServer CreateWebServer(string url)
|
||||
{
|
||||
var server = new WebServer(o => o
|
||||
.WithUrlPrefix(url)
|
||||
.WithMode(HttpListenerMode.EmbedIO))
|
||||
.WithWebApi("/api", m => m
|
||||
.WithController<MyApiController>(() => new MyApiController(AddLog)))
|
||||
.WithStaticFolder("/", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"), true);
|
||||
|
||||
// 添加请求日志中间件
|
||||
server.OnHttpException += async (context, exception) =>
|
||||
{
|
||||
AddLog($"HTTP Exception: {exception.Message}");
|
||||
await Task.CompletedTask;
|
||||
};
|
||||
|
||||
server.StateChanged += (sender, e) =>
|
||||
AddLog($"Server state changed from {e.OldState} to {e.NewState}");
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
// 线程安全的日志添加方法
|
||||
private void AddLog(string message)
|
||||
{
|
||||
var timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
|
||||
_logQueue.Enqueue($"[{timestamp}] {message}");
|
||||
}
|
||||
|
||||
// 在UI线程上处理日志队列
|
||||
private void ProcessLogQueue(object sender, EventArgs e)
|
||||
{
|
||||
while (_logQueue.TryDequeue(out var message))
|
||||
{
|
||||
LogTextBox.AppendText(message + Environment.NewLine);
|
||||
LogTextBox.ScrollToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
_logTimer.Stop();
|
||||
_cts?.Cancel();
|
||||
_server?.Dispose();
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EmbedIO" Version="3.5.2" />
|
||||
<PackageReference Include="Prism.Unity" Version="8.1.97" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\linesider_screen_bankend.Core\linesider_screen_bankend.Core.csproj" />
|
||||
<ProjectReference Include="..\Modules\linesider_screen_bankend.Modules.ModuleName\linesider_screen_bankend.Modules.ModuleName.csproj" />
|
||||
<ProjectReference Include="..\Services\linesider_screen_bankend.Services.Interfaces\linesider_screen_bankend.Services.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\Services\linesider_screen_bankend.Services\linesider_screen_bankend.Services.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
x
Reference in New Issue
Block a user