Sfoglia il codice sorgente

三代机模拟程序调试

master
pry 2 anni fa
parent
commit
0740c46a4c
11 ha cambiato i file con 272 aggiunte e 125 eliminazioni
  1. +94
    -54
      HBLConsole.Communication/LebaiHelper.cs
  2. +5
    -0
      HBLConsole.GVL/GeneralConfig.cs
  3. +39
    -25
      HBLConsole.MORKS/Control_MORKS.cs
  4. +21
    -0
      HBLConsole.Model/MessageLocStyleVisible.cs
  5. +18
    -9
      HBLConsole.Service/MessageLog.cs
  6. +30
    -0
      HBLConsole/Converter/MessageLogConverter.cs
  7. +1
    -0
      HBLConsole/Resources/ResourceDictionarys/BasicStyle.xaml
  8. +21
    -16
      HBLConsole/View/DebugView.xaml
  9. +16
    -3
      HBLConsole/View/MessageLogView.xaml
  10. +3
    -0
      HBLConsole/ViewModel/DebugViewModel.cs
  11. +24
    -18
      HBLConsole/ViewModel/ViewModelBase.cs

+ 94
- 54
HBLConsole.Communication/LebaiHelper.cs Vedi File

@@ -35,20 +35,6 @@ namespace HBLConsole.Communication


#region 且时且多设备
//取咖啡杯 set:=1 get:=101 10031
//取冰淇淋杯 set:=1 get:=101 10032
//咖啡杯检测 set:=1 get:=101 10033
//冰淇淋杯检测 set:=1 get:=101 10034
//二次取咖啡杯 set:=1 get:=101 10035
//二次取冰淇淋杯 set:=1 get:=101 10036
//接咖啡 set:=1 get:=101 10037
//接冰淇淋公共点 set:=1 get:=101 10038
//接1号冰淇淋 set:=1 get:=101 10039
//接2号冰淇淋 set:=1 get:=101 10040
//接3号冰淇淋 set:=1 get:=101 10041
//放咖啡位置 set:=1 get:=101 10042
//放冰淇淋位置 set:=1 get:=101 10043

public const int SENCE_取咖啡杯 = 10031;
public const int SENCE_取冰淇淋杯 = 10032;
public const int SENCE_咖啡杯检测 = 10033;
@@ -98,18 +84,32 @@ namespace HBLConsole.Communication
MessageLog.GetInstance.Show("乐百机器人连接成功!");
}

/// <summary>
/// 获取机器人模式状态
/// </summary>
public void GetRobotModeStatus()
{

if (robotData == null) return;
int mode = robotData.RobotMode.Mode;
IsIdle = mode == 5;
for (int i = 0; i < 14; i++)
try
{
if (RTrig.GetInstance(((ELebaiRModel)i).ToString()).Start(mode == i))
MessageLog.GetInstance.Show(((ELebaiRModel)i).ToString());
if (robotData == null) return;
int mode = robotData.RobotMode.Mode;
IsIdle = mode == 5;
for (int i = 0; i < 14; i++)
{
if (RTrig.GetInstance(((ELebaiRModel)i).ToString()).Start(mode == i))
MessageLog.GetInstance.Show(((ELebaiRModel)i).ToString());
}
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}

}

/// <summary>
/// 获取机器人速度因子
/// </summary>
public void GetSpeed()
{
//client.StartSys().GetAwaiter();
@@ -122,12 +122,21 @@ namespace HBLConsole.Communication
/// </summary>
public async void StartRobot()
{
if (robotData != null)
try
{
await client.StartSys();
await client.Sync();
MessageLog.GetInstance.Show("机器人启动成功");
if (robotData != null)
{
await client.StartSys();
await client.Sync();
MessageLog.GetInstance.Show("机器人启动成功");
}
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}


}

/// <summary>
@@ -150,10 +159,18 @@ namespace HBLConsole.Communication
/// <returns></returns>
public SignalResult GetValueAsync(int index = 0)
{
if (robotData == null) return default(SignalResult);
SignalValue signalValue = new SignalValue();
signalValue.Index = index;
return client?.GetSignal(signalValue).Result;
try
{
if (robotData == null) return default(SignalResult);
SignalValue signalValue = new SignalValue();
signalValue.Index = index;
return client?.GetSignal(signalValue).Result;
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
return default(SignalResult);
}

/// <summary>
@@ -164,11 +181,19 @@ namespace HBLConsole.Communication
/// <returns></returns>
public SignalResult SetValue(int value, int index = 0)
{
if (robotData == null) return default(SignalResult);
SignalValue signalValue = new SignalValue();
signalValue.Index = index;
signalValue.Value = value;
return client.SetSignal(signalValue).Result;
try
{
if (robotData == null) return default(SignalResult);
SignalValue signalValue = new SignalValue();
signalValue.Index = index;
signalValue.Value = value;
return client.SetSignal(signalValue).Result;
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
return default(SignalResult);
}

/// <summary>
@@ -178,11 +203,18 @@ namespace HBLConsole.Communication
/// <returns></returns>
public bool GetInput(int pin = 0)
{
if (client == null) return false;
var res = client.GetDIO(new IOPin() { Pin = pin }).Result;
if (res != null)
try
{
return res.Value == 1 ? true : false;
if (client == null) return false;
var res = client.GetDIO(new IOPin() { Pin = pin }).Result;
if (res != null)
{
return res.Value == 1 ? true : false;
}
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
return false;
}
@@ -193,26 +225,34 @@ namespace HBLConsole.Communication
/// <param name="id"></param>
public async void Scene(int id)
{
CancellationToken cancellationToken = default(CancellationToken);
var result = await client.GetTasks(new GetTasksInput { PageIndex = 1, PageSize = 1 }, cancellationToken);
var first = result?.Items?.FirstOrDefault();
var r = first == null || first.Status != Lebai.SDK.Dtos.TaskStatus.Running && first.Status != Lebai.SDK.Dtos.TaskStatus.Pause;
while (!r)
try
{
Thread.Sleep(5);
result = await client.GetTasks(new GetTasksInput { PageIndex = 1, PageSize = 1 }, cancellationToken);
first = result?.Items?.FirstOrDefault();
r = first == null || first.Status != Lebai.SDK.Dtos.TaskStatus.Running && first.Status != Lebai.SDK.Dtos.TaskStatus.Pause;
CancellationToken cancellationToken = default(CancellationToken);
var result = await client.GetTasks(new GetTasksInput { PageIndex = 1, PageSize = 1 }, cancellationToken);
var first = result?.Items?.FirstOrDefault();
var r = first == null || first.Status != Lebai.SDK.Dtos.TaskStatus.Running && first.Status != Lebai.SDK.Dtos.TaskStatus.Pause;
while (!r)
{
Thread.Sleep(5);
result = await client.GetTasks(new GetTasksInput { PageIndex = 1, PageSize = 1 }, cancellationToken);
first = result?.Items?.FirstOrDefault();
r = first == null || first.Status != Lebai.SDK.Dtos.TaskStatus.Running && first.Status != Lebai.SDK.Dtos.TaskStatus.Pause;
}
while (GetValueAsync().Value != 0)
{
Thread.Sleep(500);
}
Thread.Sleep(1000);
if (robotData == null || client == null) return;
//if (!client.GetIsCanRunTask().Result) return;
await client?.RunScene(id);
MessageLog.GetInstance.Show($"调用场景:{id}");
}
while (GetValueAsync().Value != 0)
catch (Exception ex)
{
Thread.Sleep(500);
MessageLog.GetInstance.ShowEx(ex.ToString());
}
Thread.Sleep(1000);
if (robotData == null || client == null) return;
//if (!client.GetIsCanRunTask().Result) return;
await client?.RunScene(id);
MessageLog.GetInstance.Show($"调用场景:{id}");

}
}
}

+ 5
- 0
HBLConsole.GVL/GeneralConfig.cs Vedi File

@@ -32,5 +32,10 @@ namespace HBLConsole.GVL
/// </summary>
public static ConcurrentQueue<MorkOrderPush> morkOrderPushes { get; set; } = new ConcurrentQueue<MorkOrderPush>();

/// <summary>
/// 激活本地模拟订单
/// </summary>
public static bool EnableLocalSimOrder { get; set; }

}
}

+ 39
- 25
HBLConsole.MORKS/Control_MORKS.cs Vedi File

@@ -296,7 +296,7 @@ namespace HBLConsole.MORKS
ThreadManage.GetInstance.StartLong(new Action(() =>
{
mORKS.AllowRun = mORKS.InitComplete;
GeneralConfig.Healthy = mORKS.Error && mORKS.InitComplete;
GeneralConfig.Healthy = mORKS.Error && mORKS.InitComplete && !GeneralConfig.EnableLocalSimOrder;

TakeBowlTask();

@@ -337,43 +337,62 @@ namespace HBLConsole.MORKS
/// </summary>
private void TurntableControl()
{
if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
if (GeneralConfig.EnableLocalSimOrder)
{
var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
if (result != null)
//不做轮询,直接取面,模拟订单使用
if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
{
var res = result.FirstOrDefault(P => P.BatchingLoc == mORKS.TurntableFeedbackloc.ToString());
if (mORKS.TurntableLowerLimit && res != null)
if (mORKS.TurntableLowerLimit)
{
//if (mORKS.RBTakeNoodleTask.ElementAt(0).Loc != mORKS.TurntableFeedbackloc)
TurntableStart(mORKS.TurntableFeedbackloc);
TurntableStart(mORKS.RBTakeNoodleTask.ElementAt(0).Loc);
mORKS.TurntableLocLists.Clear();
mORKS.AllowTakeNoodle = true;
MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.TurntableFeedbackloc}】号位置取面");
MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.RBTakeNoodleTask.ElementAt(0).Loc}】号位置取面");
}
else
}
}
else
{
//正常轮询
if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
{
var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
if (result != null)
{
if (!mORKS.TurntableInterlock)
var res = result.FirstOrDefault(P => P.BatchingLoc == mORKS.TurntableFeedbackloc.ToString());
if (mORKS.TurntableLowerLimit && res != null)
{
foreach (var item in result)
//if (mORKS.RBTakeNoodleTask.ElementAt(0).Loc != mORKS.TurntableFeedbackloc)
TurntableStart(mORKS.TurntableFeedbackloc);
mORKS.TurntableLocLists.Clear();
mORKS.AllowTakeNoodle = true;
MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.TurntableFeedbackloc}】号位置取面");
}
else
{
if (!mORKS.TurntableInterlock)
{
if (ushort.TryParse(item.BatchingLoc, out ushort loc))
foreach (var item in result)
{
if (mORKS.TurntableFeedbackloc != loc && !mORKS.TurntableLocLists.Contains(loc))
if (ushort.TryParse(item.BatchingLoc, out ushort loc))
{
TurntableStart(loc);
MessageLog.GetInstance.Show($"没有物料检测的启动转台控制,转台位置:[{loc}]");
break;
if (mORKS.TurntableFeedbackloc != loc && !mORKS.TurntableLocLists.Contains(loc))
{
TurntableStart(loc);
MessageLog.GetInstance.Show($"没有物料检测的启动转台控制,转台位置:[{loc}]");
break;
}
else if (mORKS.TurntableFeedbackloc == loc && !mORKS.TurntableLocLists.Contains(loc)) mORKS.TurntableLocLists.Add(loc);
}
else if (mORKS.TurntableFeedbackloc == loc && !mORKS.TurntableLocLists.Contains(loc)) mORKS.TurntableLocLists.Add(loc);
}
}
}
}
else MessageLog.GetInstance.Show("未找到可用的物料信息");
}
else MessageLog.GetInstance.Show("未找到可用的物料信息");
}


//转台到位检测
if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace && mORKS.CurrentLoc == mORKS.TurntableFeedbackloc))
{
@@ -391,13 +410,8 @@ namespace HBLConsole.MORKS
mORKS.TurntableInterlock = false;
MessageLog.GetInstance.Show("补料完成检测");
}
//if (!mORKS.TurntableLowerLimit && mORKS.TurntableLocLists.Count > 0 && !mORKS.AllowTakeNoodle)
//{
// mORKS.TurntableLocLists.Clear();
// mORKS.TurntableInterlock = false;
// MessageLog.GetInstance.Show("补料完成检测");
//}
}

}

/// <summary>


+ 21
- 0
HBLConsole.Model/MessageLocStyleVisible.cs Vedi File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Toolkit.Mvvm.ComponentModel;

namespace HBLConsole.Model
{
public class MessageLocStyleVisible : ObservableObject
{
public Color ColorStyle { get { return _mColorStyle; } set { _mColorStyle = value; OnPropertyChanged(); } }
private Color _mColorStyle;


public string LogInfo { get { return _mLogInfo; } set { _mLogInfo = value; OnPropertyChanged(); } }
private string _mLogInfo;

}
}

+ 18
- 9
HBLConsole.Service/MessageLog.cs Vedi File

@@ -14,6 +14,8 @@ namespace HBLConsole.Service
public static MessageLog GetInstance => _Instance ?? (_Instance = new MessageLog());
private MessageLog() { }

private static readonly object _lock = new object();

#region 普通消息日志
/// <summary>
/// 日志显示委托
@@ -31,10 +33,13 @@ namespace HBLConsole.Service
/// <param name="info"></param>
public void Show(string info, Color color = default(Color))
{
if (color.A == 0 && color.R == 0 && color.G == 0 && color.B == 0) color = Color.Aqua;
Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}");
LogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{info} \n\r {LogInfo}";
if (InfoNotify != null) InfoNotify(info, color);
lock (_lock)
{
if (color.A == 0 && color.R == 0 && color.G == 0 && color.B == 0) color = Color.Aqua;
Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}");
LogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{info} \n\r {LogInfo}";
if (InfoNotify != null) InfoNotify(info, color);
}
}
#endregion

@@ -42,7 +47,7 @@ namespace HBLConsole.Service
/// <summary>
/// 异常日志委托
/// </summary>
public Action<string> ExInfoNotify { get; set; }
public Action<string, Color> ExInfoNotify { get; set; }

/// <summary>
/// 异常日志信息
@@ -53,11 +58,15 @@ namespace HBLConsole.Service
/// 异常日志输出
/// </summary>
/// <param name="info"></param>
public void ShowEx(string info)
public void ShowEx(string info, Color color = default(Color))
{
Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}");
ExLogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{info} \n\r {ExLogInfo}";
if (ExInfoNotify != null) ExInfoNotify(info);
lock (_lock)
{
color = Color.Red;
Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:{info}");
ExLogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{info} \n\r {ExLogInfo}";
if (ExInfoNotify != null) ExInfoNotify(info, color);
}
}
#endregion



+ 30
- 0
HBLConsole/Converter/MessageLogConverter.cs Vedi File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;

namespace HBLConsole.Converter
{
public class MessageLogConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string aa = value.GetType().Name;
SolidColorBrush returnValue = new SolidColorBrush(Color.FromArgb(255, 0, 255, 255));
if (value != null && value is System.Drawing.Color colorStyle)
{
returnValue = new SolidColorBrush(Color.FromArgb(colorStyle.A, colorStyle.R, colorStyle.G, colorStyle.B));
}
return returnValue;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

+ 1
- 0
HBLConsole/Resources/ResourceDictionarys/BasicStyle.xaml Vedi File

@@ -13,6 +13,7 @@
<!--<con:ColorConverter x:Key="ColorConverter" />-->
<con:TextConverter x:Key="TextConverter" />
<con:VisibleConvert x:Key="VisibleConvert" />
<con:MessageLogConverter x:Key="MessageLogConverter" />
<!--#endregion-->

<!--#region 右斜边按钮-->


+ 21
- 16
HBLConsole/View/DebugView.xaml Vedi File

@@ -202,22 +202,22 @@
Template="{StaticResource CbTemplate}" />

<Button
Style="{StaticResource ButtonStyle}"
Grid.Column="3"
FontSize="14"
Margin="10 0 0 0"
Margin="10,0,0,0"
Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}"
CommandParameter="{Binding Text}"
Content="编辑" />
Content="编辑"
FontSize="14"
Style="{StaticResource ButtonStyle}" />

<Button
Grid.Column="4"
Margin="5 0 0 0"
FontSize="14"
Style="{StaticResource ButtonStyle}"
Margin="5,0,0,0"
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}"
CommandParameter="{Binding Text}"
Content="删除" />
Content="删除"
FontSize="14"
Style="{StaticResource ButtonStyle}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
@@ -238,10 +238,9 @@
</StackPanel>
</Grid>

<Grid Margin="20 0 0 0" Grid.Column="1">
<Grid Grid.Column="1" Margin="20,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="10" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition />
@@ -264,19 +263,25 @@
<Button
x:Name="button_loop"
Margin="0,0,10,0"
Command="{Binding LoopSimOrderCommand}"
Content="{Binding LoopOrderButtonContent}"
Command="{Binding LoopSimOrderCommand}"
Content="{Binding LoopOrderButtonContent}"
Style="{StaticResource ButtonStyle}" />
<!--#endregion-->

</StackPanel>


<CheckBox
Grid.Row="2"
Height="20"
VerticalAlignment="Center"
Background="#FF2AB2E7"
Content="启用本地模拟程序"
FontSize="14"
Foreground="#00c2f4"
IsChecked="{Binding EnableLocalSimOrder}"
Template="{StaticResource CbTemplate}" />
</Grid>




</Grid>




+ 16
- 3
HBLConsole/View/MessageLogView.xaml Vedi File

@@ -25,18 +25,31 @@
</UserControl.Resources>

<Grid>

<ScrollViewer
Grid.Row="1"
Margin="5"
HorizontalScrollBarVisibility="Visible"
Style="{StaticResource ScrollViewerStyle}"
VerticalScrollBarVisibility="Visible">
<TextBlock
<!--<TextBlock
FontSize="14"
Foreground="Aqua"
Text="{Binding LogMessage}"
TextWrapping="Wrap" />
TextWrapping="Wrap" />-->
<ItemsControl ItemsSource="{Binding Messages}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock
Margin="0,10,0,0"
FontSize="14"
Foreground="{Binding ColorStyle, Converter={StaticResource MessageLogConverter}}"
Text="{Binding LogInfo}"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>

+ 3
- 0
HBLConsole/ViewModel/DebugViewModel.cs Vedi File

@@ -17,6 +17,7 @@ using System.Collections.ObjectModel;
using System.Windows.Media;
using HBLConsole.DialogWindow.View;
using System.Diagnostics;
using HBLConsole.GVL;

namespace HBLConsole.ViewModel
{
@@ -94,6 +95,8 @@ namespace HBLConsole.ViewModel
});
}

public static bool EnableLocalSimOrder { get { return GeneralConfig.EnableLocalSimOrder; } set { GeneralConfig.EnableLocalSimOrder = value; OnStaticPropertyChanged(); } }

public ObservableCollection<SimOrderVisibleData> simOrderConfig
{
get


+ 24
- 18
HBLConsole/ViewModel/ViewModelBase.cs Vedi File

@@ -35,23 +35,29 @@ namespace HBLConsole.ViewModel
{
MessageLog.GetInstance.InfoNotify = new Action<string, Color>((s, c) =>
{
LogMessage = $"{DateTime.Now.ToString("HH:mm:ss")}:{s} \n\r {LogMessage}";
//Messages.Add($"{DateTime.Now.ToString("HH:mm:ss")}:{s}");
});

MessageLog.GetInstance.ExInfoNotify = new Action<string>((s) =>
{
LogMessage = $"{DateTime.Now.ToString("HH:mm:ss")}:{s} \n\r {LogMessage}";
//Messages.Add($"{DateTime.Now.ToString("HH:mm:ss")}:{s}");
IotReport.GetInstance.HttpAddLog(new BPA.Message.API请求.LogTable
{
ClientId = InternetInfo.ClientId.ToString(),
LogTime = DateTime.Now,
LogType = "1",
LogMessage = s,
LogVla = "异常",
});
});
//LogMessage = $"{DateTime.Now.ToString("HH:mm:ss")}:{s} \n\r {LogMessage}";
App.Current.Dispatcher.Invoke(() =>
{
Messages.Insert(0, new MessageLocStyleVisible() { ColorStyle = c, LogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{s}" });
});
});

MessageLog.GetInstance.ExInfoNotify = new Action<string, Color>((s, c) =>
{
//LogMessage = $"{DateTime.Now.ToString("HH:mm:ss")}:{s} \n\r {LogMessage}";
App.Current.Dispatcher.Invoke(() =>
{
Messages.Insert(0, new MessageLocStyleVisible() { ColorStyle = c, LogInfo = $"{DateTime.Now.ToString("HH:mm:ss")}:{s}" });
});
IotReport.GetInstance.HttpAddLog(new BPA.Message.API请求.LogTable
{
ClientId = InternetInfo.ClientId.ToString(),
LogTime = DateTime.Now,
LogType = "1",
LogMessage = s,
LogVla = "异常",
});
});
}


@@ -104,7 +110,7 @@ namespace HBLConsole.ViewModel
/// <summary>
/// 消息列表
/// </summary>
public static ObservableCollection<string> Messages { get; set; } = new ObservableCollection<string>();
public static ObservableCollection<MessageLocStyleVisible> Messages { get; set; } = new ObservableCollection<MessageLocStyleVisible>();

/// <summary>
/// 显示当前窗体名称


Caricamento…
Annulla
Salva