@@ -0,0 +1,14 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net6.0</TargetFramework> | |||
<ImplicitUsings>enable</ImplicitUsings> | |||
<Nullable>enable</Nullable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.Helper\BPASmartClient.Helper.csproj" /> | |||
<ProjectReference Include="..\BPASmartClinet.DataBusName\BPASmartClinet.DataBusName.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,236 @@ | |||
| |||
using BPASmartClient.Bus.DataBus; | |||
using BPASmartClient.Helper; | |||
using BPASmartClinet.DataBusName; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject 数据总线,总线入口,后续按类型分发 | |||
* author 张原川 | |||
* date 2019/6/3 9:49:03 | |||
* ***********************************************/ | |||
namespace LandStation.Bus.DataBus | |||
{ | |||
public class DataBus : Singleton<DataBus>, IDisposable | |||
{ | |||
//原始数据总线 | |||
private IDataBus<byte> _dataBus_rawdata; | |||
//MAVLINK消息总线 | |||
private IDataBus<object> _dataBus_mavMessage; | |||
//参数总线 | |||
private IDataBus<object> _dataBus_parameter; | |||
//调试消息总线 | |||
private IDataBus<string> _dataBus_message; | |||
/// <summary> | |||
/// 数据总线初始化 | |||
/// </summary> | |||
public void Initialize() | |||
{ | |||
_dataBus_rawdata = new DataBus_Byte(); | |||
_dataBus_mavMessage = new DataBus_Currency<object>(); | |||
_dataBus_parameter = new DataBus_Currency<object>(); | |||
_dataBus_message = new DataBus_Currency<string>(); | |||
} | |||
/// <summary> | |||
/// 总线开启 | |||
/// </summary> | |||
public void Start() | |||
{ | |||
Executer.GetInstance().Start(_dataBus_rawdata.StartBus, ActionKey.DataBus_Rawdata); | |||
Executer.GetInstance().Start(_dataBus_mavMessage.StartBus, ActionKey.DataBus_MAVLinkMessage); | |||
Executer.GetInstance().Start(_dataBus_message.StartBus, ActionKey.DataBus_MessageData); | |||
Executer.GetInstance().Start(_dataBus_parameter.StartBus, ActionKey.DataBus_ParameterData); | |||
//Executer.GetInstance().Start(delegate () | |||
//{ | |||
// while (true) | |||
// { | |||
// //Console.WriteLine("原始数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_rawdata.MultSubscriberCount, _dataBus_rawdata.SingleSubscriberCount); | |||
// //Console.WriteLine("MAVLink数据=====>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_mavMessage.MultSubscriberCount, _dataBus_mavMessage.SingleSubscriberCount); | |||
// //Console.WriteLine("状态数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_status.MultSubscriberCount, _dataBus_status.SingleSubscriberCount); | |||
// //Console.WriteLine("参数数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_parameter.MultSubscriberCount, _dataBus_parameter.SingleSubscriberCount); | |||
// //Console.WriteLine("消息数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_message.MultSubscriberCount, _dataBus_message.SingleSubscriberCount); | |||
// //Console.WriteLine("==============================================================================================="); | |||
// Console.WriteLine("原始数据========>{0}", _dataBus_rawdata.DataCount); | |||
// Console.WriteLine("MAVLink数据=====>{0}", _dataBus_mavMessage.DataCount); | |||
// Console.WriteLine("状态数据========>{0}", _dataBus_status.DataCount); | |||
// Console.WriteLine("参数数据========>{0}", _dataBus_parameter.DataCount); | |||
// Console.WriteLine("消息数据========>{0}", _dataBus_message.DataCount); | |||
// Console.WriteLine("==============================================================================================="); | |||
// Thread.Sleep(50); | |||
// } | |||
//}, ActionKey.DataBus_Monitor, "数据总线监控"); | |||
} | |||
/// <summary> | |||
/// 根据数据类型放入数据到对应总线 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="data">数据</param> | |||
/// <param name="simpleData">数据业务类型</param> | |||
public void Put<TData>(object data, SimpleDataType simpleData) | |||
{ | |||
switch (simpleData) | |||
{ | |||
case SimpleDataType.RAW_DATA: | |||
if (data is byte) | |||
_dataBus_rawdata.Put((byte)data); | |||
if (data is byte[]) | |||
_dataBus_rawdata.Put((byte[])data); | |||
break; | |||
case SimpleDataType.MAV_MESSAGE_DATA: | |||
_dataBus_mavMessage.Put((object)data); | |||
break; | |||
case SimpleDataType.PARAMETER: | |||
_dataBus_parameter.Put((object)data); | |||
break; | |||
case SimpleDataType.MESSAGE_DATA: | |||
_dataBus_message.Put((string)data); | |||
break; | |||
} | |||
} | |||
/// <summary> | |||
/// 订阅数据 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="action">接收数据推送回调</param> | |||
/// <param name="dataType">数据业务类型</param> | |||
public void Subscribe<TData>(Action<TData> action, SimpleDataType dataType) | |||
{ | |||
switch (dataType) | |||
{ | |||
case SimpleDataType.RAW_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_rawdata).Subscribe(action); | |||
break; | |||
case SimpleDataType.MAV_MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_mavMessage).Subscribe(action); | |||
break; | |||
case SimpleDataType.PARAMETER: | |||
((ISimpleDataBus<TData>)_dataBus_parameter).Subscribe(action); | |||
break; | |||
case SimpleDataType.MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_message).Subscribe(action); | |||
break; | |||
} | |||
} | |||
/// <summary> | |||
/// 订阅数据 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="action">接收数据推送回调</param> | |||
/// <param name="dataType">数据业务类型</param> | |||
public void UnSubscribe<TData>(Action<TData> action, SimpleDataType dataType) | |||
{ | |||
switch (dataType) | |||
{ | |||
case SimpleDataType.RAW_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_rawdata).UnSubcribe(action); | |||
break; | |||
case SimpleDataType.MAV_MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_mavMessage).UnSubcribe(action); | |||
break; | |||
case SimpleDataType.PARAMETER: | |||
((ISimpleDataBus<TData>)_dataBus_parameter).UnSubcribe(action); | |||
break; | |||
case SimpleDataType.MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_message).UnSubcribe(action); | |||
break; | |||
} | |||
} | |||
/// <summary> | |||
/// 订阅数据 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="action">接收数据推送回调</param> | |||
/// <param name="dataType">数据业务类型</param> | |||
public void Subscribe<TData>(Action<TData[]> action, SimpleDataType dataType) | |||
{ | |||
switch (dataType) | |||
{ | |||
case SimpleDataType.RAW_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_rawdata).Subscribe(action); | |||
break; | |||
case SimpleDataType.MAV_MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_mavMessage).Subscribe(action); | |||
break; | |||
case SimpleDataType.PARAMETER: | |||
((ISimpleDataBus<TData>)_dataBus_parameter).Subscribe(action); | |||
break; | |||
case SimpleDataType.MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_message).Subscribe(action); | |||
break; | |||
} | |||
} | |||
/// <summary> | |||
/// 订阅数据 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="action">接收数据推送回调</param> | |||
/// <param name="dataType">数据业务类型</param> | |||
public void UnSubscribe<TData>(Action<TData[]> action, SimpleDataType dataType) | |||
{ | |||
switch (dataType) | |||
{ | |||
case SimpleDataType.RAW_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_rawdata).UnSubcribe(action); | |||
break; | |||
case SimpleDataType.MAV_MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_mavMessage).UnSubcribe(action); | |||
break; | |||
case SimpleDataType.PARAMETER: | |||
((ISimpleDataBus<TData>)_dataBus_parameter).UnSubcribe(action); | |||
break; | |||
case SimpleDataType.MESSAGE_DATA: | |||
((ISimpleDataBus<TData>)_dataBus_message).UnSubcribe(action); | |||
break; | |||
} | |||
} | |||
/// <summary> | |||
/// 获取一个数据 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="dataType">数据业务类型</param> | |||
/// <returns>一个数据</returns> | |||
public byte GetRawdata() | |||
{ | |||
return ((IGivenDataBus<byte>)_dataBus_rawdata).Get(); | |||
} | |||
/// <summary> | |||
/// 获取多个数据 | |||
/// </summary> | |||
/// <typeparam name="TData">数据实际类型</typeparam> | |||
/// <param name="dataType">数据业务类型</param> | |||
/// <param name="length">获取数据长度</param> | |||
/// <returns>一个数据</returns> | |||
public byte[] GetRawdata(int length) | |||
{ | |||
return ((IGivenDataBus<byte>)_dataBus_rawdata).Get(length); | |||
} | |||
/// <summary> | |||
/// 释放数据总线 | |||
/// </summary> | |||
public void Dispose() | |||
{ | |||
_dataBus_rawdata.StopBus(); | |||
_dataBus_mavMessage.StopBus(); | |||
_dataBus_message.StopBus(); | |||
_dataBus_parameter.StopBus(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,98 @@ | |||
| |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject Byte类型数据总线,在订阅推送模式基础上 | |||
* 增加主动获取 | |||
* author 张原川 | |||
* date 2019/6/3 14:44:36 | |||
* ***********************************************/ | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
public class DataBus_Byte : DataBus_Currency<byte>, IGivenDataBus<byte> | |||
{ | |||
//接收数据缓冲(用以Get) | |||
//protected CircularBuffer<byte> _givenDataPool = new CircularBuffer<byte>(1 * 1024 * 1024); | |||
protected ConcurrentQueue<byte> _givenDataPool = new ConcurrentQueue<byte>(); | |||
public new int DataCount { get { return _givenDataPool.Count; } } | |||
/// <summary> | |||
/// 重写Put方法,加入givenDataPool | |||
/// </summary> | |||
public new void Put(byte data) | |||
{ | |||
if (!_running) | |||
return; | |||
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0) | |||
_dataPool.Enqueue(data); | |||
_givenDataPool.Enqueue(data); | |||
} | |||
/// <summary> | |||
/// 重写Put方法,加入givenDataPool | |||
/// </summary> | |||
public new void Put(byte[] data) | |||
{ | |||
if (!_running) | |||
return; | |||
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0) | |||
foreach (var item in data) | |||
_dataPool.Enqueue(item); | |||
foreach (var item in data) | |||
_givenDataPool.Enqueue(item); | |||
} | |||
/// <summary> | |||
/// 数据取出 | |||
/// </summary> | |||
public byte Get() | |||
{ | |||
agin: | |||
if (_givenDataPool.Count <= 0) | |||
{ | |||
Thread.Sleep(5); | |||
goto agin; | |||
} | |||
byte res; | |||
while (!_givenDataPool.TryDequeue(out res)) ; | |||
return res; | |||
} | |||
/// <summary> | |||
/// 数据取出 | |||
/// </summary> | |||
public byte[] Get(int count) | |||
{ | |||
agin: | |||
if (_givenDataPool.Count < count) | |||
{ | |||
Thread.Sleep(5); | |||
goto agin; | |||
} | |||
//Console.WriteLine(_givenDataPool.Size + "===========" + _dataPool.Size); | |||
//for (int i = 0; i < count; i++) { | |||
// _givenDataPool.TryDequeue | |||
//} | |||
int i = 0; | |||
byte[] result = new byte[count]; | |||
while (i < count) | |||
{ | |||
if (_givenDataPool.TryDequeue(out result[i])) | |||
{ | |||
i++; | |||
} | |||
} | |||
return result;// _givenDataPool.Get(count); | |||
} | |||
} | |||
} |
@@ -0,0 +1,190 @@ | |||
| |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject 通用数据总线,采取订阅推送模式 | |||
* author 张原川 | |||
* date 2019/6/3 15:03:10 | |||
* ***********************************************/ | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
public class DataBus_Currency<TData> : ISimpleDataBus<TData> | |||
{ | |||
//接收数据缓冲 | |||
//protected CircularBuffer<TData> _dataPool = new CircularBuffer<TData>(1 * 1024 * 1024); | |||
protected ConcurrentQueue<TData> _dataPool = new ConcurrentQueue<TData>(); | |||
//订阅数据回调集合 | |||
protected List<Action<TData[]>> _multDataHandlers = new List<Action<TData[]>>(); | |||
protected List<Action<TData>> _singleDataHandlers = new List<Action<TData>>(); | |||
//订阅与推送数据信号量 | |||
protected AutoResetEvent _are = new AutoResetEvent(false); | |||
//运行标识 | |||
protected bool _running = false; | |||
public int MultSubscriberCount { get { return _multDataHandlers.Count; } } | |||
public int SingleSubscriberCount { get { return _singleDataHandlers.Count; } } | |||
public int DataCount { get { return _dataPool.Count; } } | |||
/// <summary> | |||
/// 终止事件总线 | |||
/// </summary> | |||
public void Dispose() | |||
{ | |||
StopBus(); | |||
} | |||
/// <summary> | |||
/// 数据存入 | |||
/// </summary> | |||
public void Put(TData data) | |||
{ | |||
if (!_running) | |||
return; | |||
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0) | |||
_dataPool.Enqueue(data); | |||
} | |||
/// <summary> | |||
/// 数据存入 | |||
/// </summary> | |||
public void Put(TData[] data) | |||
{ | |||
if (!_running) | |||
return; | |||
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0) | |||
foreach (var item in data) | |||
_dataPool.Enqueue(item); | |||
} | |||
/// <summary> | |||
/// 开启总线 | |||
/// </summary> | |||
public void StartBus() | |||
{ | |||
_running = true; | |||
List<TData> items = new List<TData>(); | |||
_are.Set(); | |||
while (_running) | |||
{ | |||
int count = _dataPool.Count; | |||
items.Clear(); | |||
if (_singleDataHandlers.Count > 0) | |||
{ | |||
_are.WaitOne(TimeSpan.FromMilliseconds(10)); | |||
for (int i = 0; i < count; i++) | |||
{ | |||
TData data = default(TData); | |||
while (!_dataPool.TryDequeue(out data)) ; | |||
uint msgId = Convert.ToUInt32(data.GetType().GetProperty("msgid").GetValue(data)); | |||
if (msgId == 316) | |||
{ | |||
} | |||
//var item = _dataPool.Get(); | |||
//Parallel.ForEach(_singleDataHandlers, p => p.Invoke(items[items.Count - 1])); | |||
for (int j = 0; j < _singleDataHandlers.Count; j++) | |||
{ | |||
_singleDataHandlers[j].Invoke(data); | |||
} | |||
items.Add(data); | |||
} | |||
} | |||
if (_multDataHandlers.Count > 0) | |||
{ | |||
if (items.Count <= 0) | |||
{ | |||
TData data = default(TData); | |||
for (int i = 0; i < count; i++) | |||
{ | |||
while (!_dataPool.TryDequeue(out data)) ; | |||
items.Add(data); | |||
} | |||
//items.AddRange(_dataPool.Get(count)); | |||
} | |||
_are.WaitOne(TimeSpan.FromMilliseconds(10)); | |||
//Parallel.For(0, _multDataHandlers.Count, (i) => | |||
//{ | |||
// _multDataHandlers[i].Invoke(items.ToArray()); | |||
//}); | |||
for (int i = _multDataHandlers.Count - 1; i >= 0; i--) | |||
{ | |||
_multDataHandlers[i].Invoke(items.ToArray()); | |||
} | |||
} | |||
Thread.Sleep(10); | |||
_are.Set(); | |||
} | |||
} | |||
public void StopBus() | |||
{ | |||
_running = false; | |||
} | |||
/// <summary> | |||
/// 数据订阅 | |||
/// </summary> | |||
/// <param name="action">接收数据回调</param> | |||
public void Subscribe(Action<TData> action) | |||
{ | |||
if (_singleDataHandlers.Contains(action)) | |||
return; | |||
_are.Reset(); | |||
_singleDataHandlers.Add(action); | |||
_are.Set(); | |||
} | |||
/// <summary> | |||
/// 数据订阅 | |||
/// </summary> | |||
/// <param name="action">接收数据回调</param> | |||
public void Subscribe(Action<TData[]> action) | |||
{ | |||
if (_multDataHandlers.Contains(action)) | |||
return; | |||
_are.Reset(); | |||
_multDataHandlers.Add(action); | |||
_are.Set(); | |||
} | |||
/// <summary> | |||
/// 取消数据订阅 | |||
/// </summary> | |||
/// <param name="action">接收数据回调</param> | |||
public void UnSubcribe(Action<TData> action) | |||
{ | |||
if (!_singleDataHandlers.Contains(action)) | |||
return; | |||
_are.Reset(); | |||
_singleDataHandlers.Remove(action); | |||
_are.Set(); | |||
} | |||
/// <summary> | |||
/// 取消数据订阅 | |||
/// </summary> | |||
/// <param name="action">接收数据回调</param> | |||
public void UnSubcribe(Action<TData[]> action) | |||
{ | |||
if (!_multDataHandlers.Contains(action)) | |||
return; | |||
_are.Reset(); | |||
_multDataHandlers.Remove(action); | |||
_are.Set(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,149 @@ | |||
using BPASmartClient.Helper; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
/// <summary> | |||
/// 线程集中处理委托 | |||
/// </summary> | |||
/// <param name="action"></param> | |||
public delegate void ActionKeyHandle(string action); | |||
public delegate void ThreadExceptionHandle(string action, Exception ex); | |||
public delegate void ThreadExitHandle(string action); | |||
/// <summary> | |||
/// 执行器 | |||
/// </summary> | |||
public class Executer : Singleton<Executer> | |||
{ | |||
private System.Timers.Timer _timer4Monitor = new System.Timers.Timer(1000); | |||
private ConcurrentDictionary<string, Thread> _actions = new ConcurrentDictionary<string, Thread>(); | |||
private object _async = new object(); | |||
public event ThreadExceptionHandle OnThreadException; | |||
public event ThreadExitHandle ThreadExit; | |||
/// <summary> | |||
/// 构造器 | |||
/// </summary> | |||
public Executer() | |||
{ | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
public void Dispose() | |||
{ | |||
_timer4Monitor.Stop(); | |||
foreach (var th in _actions) | |||
{ | |||
try { th.Value.Abort(); } | |||
catch (ThreadAbortException) { } | |||
} | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <returns></returns> | |||
public List<Thread> GetActionInfos() | |||
{ | |||
Monitor.TryEnter(_async, 200); | |||
var actionInfos = _actions.Values.ToList(); | |||
Monitor.Exit(_async); | |||
return actionInfos; | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="key"></param> | |||
public void Abort(string key) | |||
{ | |||
Monitor.TryEnter(_async, 200); | |||
if (_actions.ContainsKey(key)) | |||
{ | |||
try { _actions[key].Abort(); } | |||
catch (ThreadAbortException) { } | |||
} | |||
Monitor.Exit(_async); | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="key"></param> | |||
/// <returns></returns> | |||
public bool ContainsKey(string key) | |||
{ | |||
Monitor.TryEnter(_async, 200); | |||
var item = _actions[key]; | |||
Monitor.Exit(_async); | |||
if (null != item) | |||
{ | |||
return true; | |||
} | |||
return false; | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="action"></param> | |||
/// <param name="name"></param> | |||
/// <param name="isBackground"></param> | |||
/// <param name="priority"></param> | |||
public void Start(Action action, string name, bool isBackground = false, ThreadPriority priority = ThreadPriority.Normal) | |||
{ | |||
Thread thread = new Thread(() => | |||
{ | |||
try | |||
{ | |||
action(); | |||
ThreadExit?.Invoke(name); | |||
} | |||
catch (Exception ex) | |||
{ | |||
OnThreadException?.Invoke(name, ex); | |||
} | |||
}); | |||
thread.IsBackground = isBackground; | |||
thread.Priority = priority; | |||
thread.Name = name; | |||
thread.Start(); | |||
Monitor.TryEnter(_async, 50); | |||
if (_actions.ContainsKey(name)) | |||
{ | |||
try { _actions[name].Abort(); } | |||
catch (ThreadAbortException) { } | |||
} | |||
_actions[name] = thread; | |||
Monitor.Exit(_async); | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="action"></param> | |||
/// <param name="timeout"></param> | |||
/// <returns></returns> | |||
public bool StartWhiteReturn(Func<bool> action, int timeout = 3) | |||
{ | |||
DateTime beginTime = DateTime.Now; | |||
bool doResult = false; | |||
while (DateTime.Now.Subtract(beginTime).TotalSeconds <= 3 && !doResult) | |||
{ | |||
doResult = action(); | |||
} | |||
return doResult; | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
public event ActionKeyHandle ActionAbort; | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
public event ActionKeyHandle ActionStarted; | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject 数据总线接口 | |||
* author 张原川 | |||
* date 2019/6/3 11:33:57 | |||
* ***********************************************/ | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
/// <summary> | |||
/// 数据总线接口 | |||
/// </summary> | |||
public interface IDataBus<TData> | |||
{ | |||
/// <summary> | |||
/// 多数据订阅数量 | |||
/// </summary> | |||
int MultSubscriberCount { get; } | |||
/// <summary> | |||
/// 单数据订阅数量 | |||
/// </summary> | |||
int SingleSubscriberCount { get; } | |||
/// <summary> | |||
/// 数据量 | |||
/// </summary> | |||
int DataCount { get; } | |||
/// <summary> | |||
/// 开启总线 | |||
/// </summary> | |||
void StartBus(); | |||
/// <summary> | |||
/// 关闭总线 | |||
/// </summary> | |||
void StopBus(); | |||
/// <summary> | |||
/// 数据放入总线 | |||
/// </summary> | |||
/// <param name="data">数据</param> | |||
void Put(TData data); | |||
/// <summary> | |||
/// 数据放入总线 | |||
/// </summary> | |||
/// <param name="data">数据</param> | |||
void Put(TData[] data); | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject 数据总线接口,定义主动取得数据 | |||
* author 张原川 | |||
* date 2019/6/3 11:25:11 | |||
* ***********************************************/ | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
public interface IGivenDataBus<TData>: IDataBus<TData> | |||
{ | |||
/// <summary> | |||
/// 数据取出 | |||
/// </summary> | |||
/// <returns></returns> | |||
TData Get(); | |||
/// <summary> | |||
/// 数据取出 | |||
/// </summary> | |||
/// <returns></returns> | |||
TData[] Get(int count); | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject 数据总线接口,定义原始数据、MAVLINK消息、状态数据、消息数据标准 | |||
* author 张原川 | |||
* date 2019/6/3 9:50:01 | |||
* ***********************************************/ | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
interface ISimpleDataBus<TData>: IDataBus<TData>,IDisposable | |||
{ | |||
/// <summary> | |||
/// 订阅总线数据 | |||
/// </summary> | |||
/// <param name="action">数据类型</param> | |||
void Subscribe(Action<TData> action); | |||
void Subscribe(Action<TData[]> action); | |||
/// <summary> | |||
/// 取消订阅数据 | |||
/// </summary> | |||
/// <param name="action">数据类型</param> | |||
void UnSubcribe(Action<TData> action); | |||
void UnSubcribe(Action<TData[]> action); | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.Bus.DataBus | |||
{ | |||
public enum SimpleDataType | |||
{ | |||
/// <summary> | |||
/// 原始数据总线 | |||
/// </summary> | |||
RAW_DATA, | |||
/// <summary> | |||
/// MAVLINK消息总线 | |||
/// </summary> | |||
MAV_MESSAGE_DATA, | |||
/// <summary> | |||
/// 全局状态数据总线 | |||
/// </summary> | |||
STATUS_DATA, | |||
/// <summary> | |||
/// 参数总线 | |||
/// </summary> | |||
PARAMETER, | |||
/// <summary> | |||
/// 调试消息总线 | |||
/// </summary> | |||
MESSAGE_DATA | |||
} | |||
} |
@@ -0,0 +1,108 @@ | |||
| |||
using BPASmartClient.Bus.EventBus; | |||
using BPASmartClient.Helper; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
/* *********************************************** | |||
* subject 事件总线,总线入口,后续按类型分发 | |||
* author 张原川 | |||
* date 2019/6/3 15:49:03 | |||
* ***********************************************/ | |||
namespace LandStation.Bus | |||
{ | |||
public class EventBus : Singleton<EventBus> | |||
{ | |||
//事件处理委托 | |||
public delegate void EventCallBackHandle(params object[] args); | |||
//事件处理委托 | |||
public delegate void EventHandle(IEvent @event, EventCallBackHandle callBack = null); | |||
//事件订阅者集合 | |||
private ConcurrentDictionary<Type, List<EventHandle>> _eventHandls = new ConcurrentDictionary<Type, List<EventHandle>>(); | |||
/// <summary> | |||
/// 事件订阅 | |||
/// </summary> | |||
public void Subscribe<TEvent>(EventHandle handle) | |||
{ | |||
if (!_eventHandls.ContainsKey(typeof(TEvent))) | |||
_eventHandls.TryAdd(typeof(TEvent), new List<EventHandle>()); | |||
lock (_eventHandls) | |||
_eventHandls[typeof(TEvent)].Add(handle); | |||
} | |||
/// <summary> | |||
/// 事件退订 | |||
/// </summary> | |||
public void UnSubscribe<TEvent>(EventHandle handle) | |||
{ | |||
if (_eventHandls.ContainsKey(typeof(TEvent))) | |||
{ | |||
if (_eventHandls[typeof(TEvent)].Contains(handle)) | |||
{ | |||
lock (_eventHandls) | |||
_eventHandls[typeof(TEvent)].Remove(handle); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 事件发布,不带返回 | |||
/// </summary> | |||
public void Publish<TEvent>(TEvent @event) where TEvent : IEvent | |||
{ | |||
if (_eventHandls.ContainsKey(typeof(TEvent))) | |||
{ | |||
for (int i = _eventHandls[typeof(TEvent)].Count - 1; i >= 0; i--) | |||
_eventHandls[typeof(TEvent)][i](@event); | |||
//_eventHandls[typeof(TEvent)].ForEach(p => | |||
//{ | |||
// p(@event); | |||
//}); | |||
} | |||
} | |||
/// <summary> | |||
/// 事件发布,带返回 | |||
/// </summary> | |||
public void Publish<TEvent>(TEvent @event, EventCallBackHandle eventCallBack) where TEvent : IEvent | |||
{ | |||
List<object> result = new List<object>(); | |||
if (_eventHandls.ContainsKey(typeof(TEvent))) | |||
{ | |||
//_eventHandls[typeof(TEvent)].ForEach(p => | |||
//{ | |||
// p(@event, delegate (object[] args) | |||
// { | |||
// result.AddRange(args); | |||
// }); | |||
//}); | |||
for (int i = _eventHandls[typeof(TEvent)].Count - 1; i >= 0; i--) | |||
{ | |||
_eventHandls[typeof(TEvent)][i](@event, delegate (object[] args) | |||
{ | |||
result.AddRange(args); | |||
}); | |||
} | |||
} | |||
eventCallBack.Invoke(result.ToArray()); | |||
} | |||
/// <summary> | |||
/// 事件总线释放 | |||
/// </summary> | |||
public void Dispose() | |||
{ | |||
_eventHandls.Clear(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.Bus.EventBus | |||
{ | |||
/// <summary> | |||
/// 事件接口 | |||
/// </summary> | |||
public interface IEvent | |||
{ | |||
int DeviceId { get; set; } | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
/* ============================================================================== | |||
* 功能描述: | |||
* 创 建 者:张原川 | |||
* 创建日期:2016/10/10 16:50:12 | |||
* ==============================================================================*/ | |||
using BPASmartClient.Bus.EventBus; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
namespace LandStation.Bus | |||
{ | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
public static class IEventExtends | |||
{ | |||
#region Methods - Public | |||
public static void Publish<TEvent>(this TEvent message) where TEvent : class, IEvent | |||
{ | |||
EventBus.GetInstance().Publish<TEvent>(message); | |||
} | |||
public static void Publish<TEvent>(this TEvent message, EventBus.EventCallBackHandle eventCallBack) where TEvent : class, IEvent | |||
{ | |||
EventBus.GetInstance().Publish<TEvent>(message, eventCallBack); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net6.0</TargetFramework> | |||
<ImplicitUsings>enable</ImplicitUsings> | |||
<Nullable>enable</Nullable> | |||
</PropertyGroup> | |||
</Project> |
@@ -0,0 +1,34 @@ | |||
using System.Collections.Concurrent; | |||
namespace BPASmartClient.DATABUS | |||
{ | |||
/// <summary> | |||
/// 数据总线 | |||
/// </summary> | |||
public class Class_DataBus | |||
{ | |||
#region 单例模式 | |||
public static Class_DataBus dataBus = null; | |||
public static Class_DataBus GetInstance() | |||
{ | |||
if (dataBus == null) | |||
{ | |||
dataBus = new Class_DataBus(); | |||
} | |||
return dataBus; | |||
} | |||
#endregion | |||
#region 基础配置 | |||
#endregion | |||
#region 实时数据->大数据量 | |||
/// <summary> | |||
/// 设备数据 | |||
/// </summary> | |||
public ConcurrentDictionary<string, object> Dic_DeviceData = new ConcurrentDictionary<string, object>(); //原始目标链表 | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net6.0</TargetFramework> | |||
<ImplicitUsings>enable</ImplicitUsings> | |||
<Nullable>enable</Nullable> | |||
</PropertyGroup> | |||
</Project> |
@@ -0,0 +1,25 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.MessageName | |||
{ | |||
/// <summary> | |||
/// 数据订阅主题管理中心 | |||
/// </summary> | |||
public class DataName | |||
{ | |||
#region XX数据 | |||
/// <summary> | |||
/// xxx消息 | |||
/// | |||
/// </summary> | |||
[Description("消息备注"), Browsable(true)] | |||
public static string xxx = "xxx"; | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
using System.ComponentModel; | |||
namespace BPASmartClient.MessageName | |||
{ | |||
/// <summary> | |||
/// 消息名称管理中心 | |||
/// 特性:Description,消息备注 | |||
/// Browsable,是否使用 | |||
/// </summary> | |||
public class MessageName | |||
{ | |||
#region XX消息 | |||
/// <summary> | |||
/// xxx消息 | |||
/// | |||
/// </summary> | |||
[Description("消息备注"),Browsable(true)] | |||
public static string xxx = "xxx"; | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,197 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel; | |||
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.Animation; | |||
using System.Windows.Media.Imaging; | |||
using System.Windows.Navigation; | |||
using System.Windows.Shapes; | |||
namespace BPASmartClient.SCADAControl | |||
{ | |||
/// <summary> | |||
/// 新测试仪表盘 | |||
/// </summary> | |||
public class ArcGauge : Control, IExecutable | |||
{ | |||
public ArcGauge() | |||
{ | |||
Width = 300; | |||
Height = 300; | |||
SetCurrentValue(ValueProperty, 0d); | |||
SetCurrentValue(MinValueProperty, 0d); | |||
SetCurrentValue(MaxValueProperty, 100d); | |||
} | |||
private void InitTick() | |||
{ | |||
// 画大刻度 | |||
for (int i = 0; i < 11; i++) | |||
{ | |||
Line line = new Line(); | |||
line.X1 = 0; | |||
line.Y1 = 0; | |||
line.X2 = 0; | |||
line.Y2 = 12; | |||
line.Stroke = Brushes.White; | |||
line.StrokeThickness = 2; | |||
line.HorizontalAlignment = HorizontalAlignment.Center; | |||
line.RenderTransformOrigin = new Point(0.5, 0.5); | |||
line.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 }; | |||
bdGrid.Children.Add(line); | |||
DrawText(); | |||
} | |||
// 画小刻度 | |||
for (int i = 0; i < 10; i++) | |||
{ | |||
var start = -140 + 28 * i + 2.8; | |||
for (int j = 0; j < 9; j++) | |||
{ | |||
Line line = new Line(); | |||
line.X1 = 0; | |||
line.Y1 = 0; | |||
line.X2 = 0; | |||
line.Y2 = 6; | |||
line.Stroke = Brushes.White; | |||
line.StrokeThickness = 1; | |||
line.HorizontalAlignment = HorizontalAlignment.Center; | |||
line.RenderTransformOrigin = new Point(0.5, 0.5); | |||
line.RenderTransform = new RotateTransform() { Angle = start + j * 2.8 }; | |||
bdGrid.Children.Add(line); | |||
} | |||
} | |||
} | |||
List<TextBlock> textLabels = new List<TextBlock>(); | |||
private void DrawText() | |||
{ | |||
foreach (var item in textLabels) | |||
{ | |||
bdGrid.Children.Remove(item); | |||
} | |||
textLabels.Clear(); | |||
var per = MaxValue / 10; | |||
for (int i = 0; i < 11; i++) | |||
{ | |||
TextBlock textBlock = new TextBlock(); | |||
textBlock.Text = $"{MinValue + (per * i)}"; | |||
textBlock.HorizontalAlignment = HorizontalAlignment.Center; | |||
textBlock.RenderTransformOrigin = new Point(0.5, 0.5); | |||
textBlock.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 }; | |||
textBlock.Margin = new Thickness(12); | |||
textBlock.Foreground = Brushes.White; | |||
bdGrid.Children.Add(textBlock); | |||
textLabels.Add(textBlock); | |||
} | |||
} | |||
static ArcGauge() | |||
{ | |||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ArcGauge), new FrameworkPropertyMetadata(typeof(ArcGauge))); | |||
} | |||
RotateTransform rotateTransform; | |||
Grid bdGrid; | |||
public override void OnApplyTemplate() | |||
{ | |||
base.OnApplyTemplate(); | |||
rotateTransform = GetTemplateChild("PointRotate") as RotateTransform; | |||
bdGrid = GetTemplateChild("bdGrid") as Grid; | |||
Refresh(); | |||
InitTick(); | |||
} | |||
private bool isExecuteState; | |||
public bool IsExecuteState | |||
{ | |||
get { return isExecuteState; } | |||
set | |||
{ | |||
isExecuteState = value; | |||
if (IsExecuteState) | |||
{ | |||
Register(); | |||
} | |||
} | |||
} | |||
[Category("值设定")] | |||
public double Value | |||
{ | |||
get { return (double)GetValue(ValueProperty); } | |||
set { SetValue(ValueProperty, value); } | |||
} | |||
public static readonly DependencyProperty ValueProperty = | |||
DependencyProperty.Register("Value", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); | |||
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as ArcGauge)?.Refresh(); | |||
[Category("值设定")] | |||
public double MinValue | |||
{ | |||
get { return (double)GetValue(MinValueProperty); } | |||
set { SetValue(MinValueProperty, value); } | |||
} | |||
public static readonly DependencyProperty MinValueProperty = | |||
DependencyProperty.Register("MinValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); | |||
[Category("值设定")] | |||
public double MaxValue | |||
{ | |||
get { return (double)GetValue(MaxValueProperty); } | |||
set { SetValue(MaxValueProperty, value); } | |||
} | |||
public string ControlType => "控件"; | |||
public static readonly DependencyProperty MaxValueProperty = | |||
DependencyProperty.Register("MaxValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); | |||
private void Refresh() | |||
{ | |||
if (rotateTransform == null) | |||
return; | |||
DrawText(); | |||
DoubleAnimation da = new DoubleAnimation(); | |||
da.Duration = new Duration(TimeSpan.FromMilliseconds(350)); | |||
da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; | |||
if (Value > MaxValue) | |||
{ | |||
rotateTransform.Angle = 140; | |||
da.To = 140; | |||
} | |||
else if (Value < MinValue) | |||
{ | |||
rotateTransform.Angle = -140; | |||
da.To = -140; | |||
} | |||
else | |||
{ | |||
var range = MaxValue - MinValue; | |||
var process = Value / range; | |||
var tAngle = process * 280 - 140; | |||
rotateTransform.Angle = tAngle; | |||
da.To = tAngle; | |||
} | |||
rotateTransform.BeginAnimation(RotateTransform.AngleProperty, da); | |||
} | |||
public void Register() | |||
{ | |||
Refresh(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,10 @@ | |||
using System.Windows; | |||
[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) | |||
)] |
@@ -0,0 +1,17 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net6.0-windows</TargetFramework> | |||
<Nullable>enable</Nullable> | |||
<UseWPF>true</UseWPF> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<None Remove="Images\光柱.png" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Resource Include="Images\光柱.png" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,22 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.SCADAControl | |||
{ | |||
public interface IExecutable | |||
{ | |||
/// <summary> | |||
/// 是否执行 | |||
/// </summary> | |||
bool IsExecuteState { get; set; } | |||
/// <summary> | |||
/// 运行程序 注册事件 | |||
/// </summary> | |||
void Register(); | |||
string ControlType { get; } | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
<UserControl x:Class="BPASmartClient.SCADAControl.Silos" | |||
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:BPASmartClient.SCADAControl" | |||
mc:Ignorable="d" | |||
d:DesignHeight="270" d:DesignWidth="180" > | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Bottom" | |||
Margin="0 0 0 35" | |||
FontSize="25" | |||
Foreground="#FFCCD61F" | |||
Text="{Binding Title,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> | |||
<TextBlock | |||
Grid.Row="1" | |||
Margin="0,25,0,0" | |||
HorizontalAlignment="Center" | |||
FontSize="20" | |||
Foreground="#FF0084FF" | |||
Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> | |||
<TextBlock | |||
Grid.Row="1" | |||
Margin="0,70,0,0" | |||
HorizontalAlignment="Center" | |||
FontSize="20" | |||
Foreground="#FF0084FF" | |||
Text="{Binding Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> | |||
<Image | |||
Grid.RowSpan="2" | |||
Source="/BPASmartClient.SCADAControl;component/Images/光柱.png" | |||
Stretch="Fill" /> | |||
</Grid> | |||
</UserControl> |
@@ -0,0 +1,96 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel; | |||
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 BPASmartClient.SCADAControl | |||
{ | |||
/// <summary> | |||
/// Silos.xaml 的交互逻辑 | |||
/// 物料仓 | |||
/// </summary> | |||
public partial class Silos : UserControl, IExecutable | |||
{ | |||
public Silos() | |||
{ | |||
InitializeComponent(); | |||
this.DataContext = this; | |||
Width = 180; | |||
Height = 270; | |||
Value = 25.23; | |||
Title = "香料"; | |||
Text = "1 号仓"; | |||
} | |||
public string ControlType => "物料仓"; | |||
private bool isExecuteState; | |||
public bool IsExecuteState | |||
{ | |||
get { return isExecuteState; } | |||
set | |||
{ | |||
isExecuteState = value; | |||
if (IsExecuteState) | |||
{ | |||
IsEnabled = true; | |||
Register(); | |||
Style = null; | |||
} | |||
} | |||
} | |||
#region 属性 | |||
[Category("值设定")] | |||
public double Value | |||
{ | |||
get { return (double)GetValue(ValueProperty); } | |||
set { SetValue(ValueProperty, value); } | |||
} | |||
public static readonly DependencyProperty ValueProperty = | |||
DependencyProperty.Register("Value", typeof(double), typeof(Silos), new PropertyMetadata(0d, OnValueChanged)); | |||
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as Silos)?.Refresh(); | |||
[Category("值设定")] | |||
public string Text | |||
{ | |||
get { return (string)GetValue(TextProperty); } | |||
set { SetValue(TextProperty, value); } | |||
} | |||
public static readonly DependencyProperty TextProperty = | |||
DependencyProperty.Register("Text", typeof(string), typeof(Silos), new PropertyMetadata(string.Empty)); | |||
[Category("值设定")] | |||
public string Title | |||
{ | |||
get { return (string)GetValue(TitleProperty); } | |||
set { SetValue(TitleProperty, value); } | |||
} | |||
public static readonly DependencyProperty TitleProperty = | |||
DependencyProperty.Register("Title", typeof(string), typeof(Silos), new PropertyMetadata(string.Empty)); | |||
#endregion | |||
#region 函数 | |||
public void Refresh() | |||
{ | |||
} | |||
#endregion | |||
public void Register() | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,96 @@ | |||
<ResourceDictionary | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:local="clr-namespace:BPASmartClient.SCADAControl" | |||
xmlns:ctrl="clr-namespace:BPASmartClient.SCADAControl"> | |||
<!--<Style TargetType="{x:Type local:CustomControl1}"> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type local:CustomControl1}"> | |||
<Border Background="{TemplateBinding Background}" | |||
BorderBrush="{TemplateBinding BorderBrush}" | |||
BorderThickness="{TemplateBinding BorderThickness}"> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style>--> | |||
<Style TargetType="{x:Type ctrl:ArcGauge}"> | |||
<Setter Property="Background" Value="#646464"/> | |||
<Setter Property="Foreground" Value="Black"/> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type ctrl:ArcGauge}"> | |||
<Border Margin="10"> | |||
<Grid Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}"> | |||
<Ellipse Fill="#FF3B3B3B"/> | |||
<Grid RenderTransformOrigin="0.5,0.5" Margin="2"> | |||
<Grid.RenderTransform> | |||
<TransformGroup> | |||
<RotateTransform Angle="{Binding Path=Angle,ElementName=PointRotate}"/> | |||
</TransformGroup> | |||
</Grid.RenderTransform> | |||
<Ellipse Width="16" Height="14" Fill="Orange" VerticalAlignment="Top" > | |||
<Ellipse.Effect> | |||
<BlurEffect Radius="12"/> | |||
</Ellipse.Effect> | |||
</Ellipse> | |||
</Grid> | |||
<Grid x:Name="bdGrid" Margin="12" UseLayoutRounding="True" ClipToBounds="True"> | |||
<Ellipse> | |||
<Ellipse.Fill> | |||
<RadialGradientBrush> | |||
<GradientStop Color="#4D000000"/> | |||
</RadialGradientBrush> | |||
</Ellipse.Fill> | |||
</Ellipse> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition/> | |||
<ColumnDefinition Width="2*"/> | |||
<ColumnDefinition/> | |||
</Grid.ColumnDefinitions> | |||
<Grid.RowDefinitions> | |||
<RowDefinition/> | |||
<RowDefinition Height="2*"/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<Ellipse Stroke="#464646" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/> | |||
<Ellipse Stroke="#959595" Margin="4" StrokeThickness="6" Grid.Column="1" Grid.Row="1"/> | |||
<Ellipse Stroke="#464646" Margin="14" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/> | |||
</Grid> | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<Path Data="M5,0 5,0 10,120 0,120z" Fill="#0FA9CE" Stretch="Uniform" Margin="0 30 0 0" RenderTransformOrigin="0.5,1" HorizontalAlignment="Center"> | |||
<Path.RenderTransform> | |||
<TransformGroup> | |||
<RotateTransform x:Name="PointRotate"/> | |||
</TransformGroup> | |||
</Path.RenderTransform> | |||
</Path> | |||
</Grid> | |||
<Ellipse Width="28" Height="28" Fill="Black"> | |||
<Ellipse.Effect> | |||
<DropShadowEffect Color="#0FA9CE" ShadowDepth="0" Direction="0" BlurRadius="16"/> | |||
</Ellipse.Effect> | |||
</Ellipse> | |||
<Border VerticalAlignment="Bottom" BorderBrush="#10ABD1" BorderThickness="2" Margin="0 0 0 12" Background="Black" Padding="4 2" HorizontalAlignment="Center"> | |||
<TextBlock Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent},StringFormat={}{0:f1}}" FontSize="16" Width="46" TextAlignment="Center" Foreground="White"/> | |||
</Border> | |||
</Grid> | |||
</Grid> | |||
</Border> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
</ResourceDictionary> |
@@ -132,7 +132,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.JXJFoodBigSt | |||
EndProject | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.JXJFoodSmallStation", "BPASmartClient.JXJFoodSmallStation\BPASmartClient.JXJFoodSmallStation.csproj", "{D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFDemo", "WPFDemo\WPFDemo.csproj", "{A456D582-D910-4CA2-8620-6D8F63344B47}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WPFDemo", "WPFDemo\WPFDemo.csproj", "{A456D582-D910-4CA2-8620-6D8F63344B47}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.SCADA", "0.SCADA", "{7B0175AD-BB74-4A98-B9A7-1E289032485E}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MessageName", "BPASmartClient.MessageName\BPASmartClient.MessageName.csproj", "{0D769B3B-0332-4DB9-A657-B739EDB28567}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DATABUS", "BPASmartClient.DATABUS\BPASmartClient.DATABUS.csproj", "{7C1AF86E-867C-427E-90DB-6473D88F51EB}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SCADAControl", "BPASmartClient.SCADAControl\BPASmartClient.SCADAControl.csproj", "{6A3FC66D-0B89-45E8-B39B-9D81538002D1}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.数据中心", "1.数据中心", "{7BED8969-7EA7-409C-8BBC-D2777ECDA2F1}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.消息名称管理", "2.消息名称管理", "{28BE5235-2399-4EBA-B1F0-88E0F32AC869}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.组态控件集", "3.组态控件集", "{5300552F-560D-474A-8D96-0A2747D08F64}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
@@ -1288,6 +1302,66 @@ Global | |||
{A456D582-D910-4CA2-8620-6D8F63344B47}.Release|x64.Build.0 = Release|Any CPU | |||
{A456D582-D910-4CA2-8620-6D8F63344B47}.Release|x86.ActiveCfg = Release|Any CPU | |||
{A456D582-D910-4CA2-8620-6D8F63344B47}.Release|x86.Build.0 = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM64.ActiveCfg = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM64.Build.0 = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x64.Build.0 = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x86.Build.0 = Debug|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM.Build.0 = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM64.ActiveCfg = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM64.Build.0 = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x64.ActiveCfg = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x64.Build.0 = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x86.ActiveCfg = Release|Any CPU | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x86.Build.0 = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM64.ActiveCfg = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM64.Build.0 = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x64.Build.0 = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x86.Build.0 = Debug|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM.Build.0 = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM64.ActiveCfg = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM64.Build.0 = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x64.ActiveCfg = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x64.Build.0 = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x86.ActiveCfg = Release|Any CPU | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x86.Build.0 = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM64.ActiveCfg = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM64.Build.0 = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x64.Build.0 = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x86.Build.0 = Debug|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM.Build.0 = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM64.ActiveCfg = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM64.Build.0 = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x64.ActiveCfg = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x64.Build.0 = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x86.ActiveCfg = Release|Any CPU | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x86.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -1350,6 +1424,12 @@ Global | |||
{FA695D7E-6F12-4483-A16D-8494609FAE68} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} | |||
{D609C4CF-FA5C-4D39-B12F-07A60FFE5E40} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} | |||
{A456D582-D910-4CA2-8620-6D8F63344B47} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} | |||
{0D769B3B-0332-4DB9-A657-B739EDB28567} = {28BE5235-2399-4EBA-B1F0-88E0F32AC869} | |||
{7C1AF86E-867C-427E-90DB-6473D88F51EB} = {7BED8969-7EA7-409C-8BBC-D2777ECDA2F1} | |||
{6A3FC66D-0B89-45E8-B39B-9D81538002D1} = {5300552F-560D-474A-8D96-0A2747D08F64} | |||
{7BED8969-7EA7-409C-8BBC-D2777ECDA2F1} = {7B0175AD-BB74-4A98-B9A7-1E289032485E} | |||
{28BE5235-2399-4EBA-B1F0-88E0F32AC869} = {7B0175AD-BB74-4A98-B9A7-1E289032485E} | |||
{5300552F-560D-474A-8D96-0A2747D08F64} = {7B0175AD-BB74-4A98-B9A7-1E289032485E} | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | |||