You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

699 lines
29 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Txgy.EWS.Client.Common;
using Txgy.EWS.Client.Common.MessageEvents;
using Txgy.EWS.Client.Entity;
using Microsoft.Win32;
using Forms = System.Windows.Forms;
namespace Txgy.EWS.Client.SysModule.ViewModels
{
public class SystemSettingsViewModel : BindableBase
{
private const string AdvancedSettingsTargetView = "SystemSettingsAdvanced";
private const string ResourcesDirectoryName = "resources";
private const string ResourcesRelativePrefix = "\\resources\\";
private static readonly string[] AdvancedSettingsFallbackTargetViews =
{
"MenuManagementView",
"RoleManagementView",
"UserManagementView"
};
private readonly IEventAggregator _eventAggregator;
private string _statusMessage;
private Brush _statusBrush = Brushes.Gray;
private bool _canEditSystemSettings;
public SystemSettingsViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
CanEditAdvancedSettings = HasAdvancedSettingsPermission();
ReloadFromConfig();
}
public string ConfigPath => BusinessConfigManager.ConfigPath;
public string StatusMessage
{
get => _statusMessage;
set => SetProperty(ref _statusMessage, value);
}
public Brush StatusBrush
{
get => _statusBrush;
set => SetProperty(ref _statusBrush, value);
}
public bool CanEditAdvancedSettings { get; }
public Visibility AdvancedSettingsVisibility => CanEditAdvancedSettings ? Visibility.Visible : Visibility.Collapsed;
public bool CanEditSystemSettings
{
get => _canEditSystemSettings;
set
{
if (SetProperty(ref _canEditSystemSettings, value))
{
RaisePropertyChanged(nameof(SystemSettingsReadOnly));
RaisePropertyChanged(nameof(SystemSettingsEditButtonText));
}
}
}
public bool SystemSettingsReadOnly => !CanEditSystemSettings;
public string SystemSettingsEditButtonText => CanEditSystemSettings ? "保存" : "高级修改";
public string ApiDomain { get; set; }
public string AlarmSetting { get; set; }
public string AlarmLevelConfig { get; set; }
public string ReportEventLevelSetting { get; set; }
public string WorkAreaFilePath { get; set; }
public string StationsCsvFilePath { get; set; }
public string CadDwgFilePath { get; set; }
public string DwgJsonSetting { get; set; }
public string WavesMseedFilePath { get; set; }
public string WavesTxtFilePath { get; set; }
public string LocalSqLiteDb { get; set; }
public string DwgSettings { get; set; }
public string CadSettingsFileName { get; set; }
public bool IsDesign { get; set; }
public bool IsRealtime { get; set; }
public string RefreshInterval { get; set; }
public string DataLookbackHours { get; set; }
public string DataCacheTimeLenMins { get; set; }
public string TencentMySql { get; set; }
public string RealtimeResultTable { get; set; }
public string RealtimeWaveDataTable { get; set; }
public string RealtimeFocalmechanismTable { get; set; }
public string PostResultTable { get; set; }
public string PostWaveDataTable { get; set; }
public string PostFocalmechanismTable { get; set; }
public string CommpanyName { get; set; }
public string SystemNameCn { get; set; }
public string SystemNameEn { get; set; }
public string WorkAreaName { get; set; }
public string SystemShortName { get; set; }
public string DailyReportStartTime { get; set; }
public string DailyReportPlanOffsetX { get; set; }
public string DailyReportPlanOffsetY { get; set; }
public string BaseX { get; set; }
public string BaseY { get; set; }
public string BaseZ { get; set; }
public ICommand ReloadCommand => new DelegateCommand(ReloadFromConfig);
public ICommand ApplyCommand => new DelegateCommand(ApplyConfig);
public ICommand BrowseResourceFileCommand => new DelegateCommand<string>(BrowseResourceFile);
public ICommand BrowseLocalFileCommand => new DelegateCommand<string>(BrowseLocalFile);
public ICommand BrowseFolderCommand => new DelegateCommand<string>(BrowseFolder);
public ICommand ToggleSystemSettingsEditCommand => new DelegateCommand(ToggleSystemSettingsEdit);
private void ReloadFromConfig()
{
try
{
Load(BusinessConfigManager.Read());
SetStatus("已读取最新配置", Brushes.Gray);
}
catch (Exception ex)
{
SetStatus($"读取配置失败:{ex.Message}", Brushes.Red);
}
}
private void ApplyConfig()
{
TryApplyConfig();
}
private bool TryApplyConfig()
{
try
{
var previousConfig = BusinessConfigManager.Current;
var config = BuildConfig(previousConfig);
var savedConfig = BusinessConfigManager.Save(config);
var shouldReloadWarningData = ShouldReloadWarningData(previousConfig, savedConfig);
GlobalConfig.ApplyBusinessConfig(savedConfig);
_eventAggregator.GetEvent<BusinessConfigChangedEvent>().Publish(savedConfig);
if (shouldReloadWarningData)
{
_eventAggregator.GetEvent<ReloadWarningDataEvent>().Publish();
}
Load(savedConfig);
SetStatus($"配置已应用:{DateTime.Now:HH:mm:ss}", Brushes.Green);
return true;
}
catch (Exception ex)
{
SetStatus($"应用失败:{ex.Message}", Brushes.Red);
return false;
}
}
private void ToggleSystemSettingsEdit()
{
if (CanEditSystemSettings)
{
if (TryApplyConfig())
{
CanEditSystemSettings = false;
SetStatus($"系统参数已保存:{DateTime.Now:HH:mm:ss}", Brushes.Green);
}
return;
}
var result = MessageBox.Show(
"系统参数会影响系统名称显示和缓存目录,是否确认修改系统参数?",
"高级修改",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result != MessageBoxResult.Yes)
{
return;
}
CanEditSystemSettings = true;
SetStatus("系统参数已解锁", Brushes.Gray);
}
private void BrowseResourceFile(string targetName)
{
var resourcesDirectory = GetResourcesDirectory();
if (!Directory.Exists(resourcesDirectory))
{
SetStatus($"resources目录不存在{resourcesDirectory}", Brushes.Red);
return;
}
var dialog = new OpenFileDialog
{
CheckFileExists = true,
Multiselect = false,
Title = "选择resources目录下的文件",
Filter = GetFileFilter(targetName),
InitialDirectory = GetInitialDirectory(GetPathValue(targetName), true)
};
if (dialog.ShowDialog() != true)
{
return;
}
if (!TryGetResourcesRelativePath(dialog.FileName, out var relativePath))
{
SetStatus("请选择resources目录下的文件", Brushes.Red);
return;
}
SetPathValue(targetName, relativePath);
SetStatus($"已选择:{relativePath}", Brushes.Gray);
}
private void BrowseLocalFile(string targetName)
{
var dialog = new OpenFileDialog
{
CheckFileExists = true,
Multiselect = false,
Title = "选择文件",
Filter = GetFileFilter(targetName),
InitialDirectory = GetInitialDirectory(GetPathValue(targetName), false)
};
if (dialog.ShowDialog() != true)
{
return;
}
SetPathValue(targetName, dialog.FileName);
SetStatus($"已选择:{dialog.FileName}", Brushes.Gray);
}
private void BrowseFolder(string targetName)
{
using (var dialog = new Forms.FolderBrowserDialog())
{
dialog.Description = "选择目录";
dialog.SelectedPath = GetInitialDirectory(GetPathValue(targetName), false);
if (dialog.ShowDialog() != Forms.DialogResult.OK || string.IsNullOrWhiteSpace(dialog.SelectedPath))
{
return;
}
SetPathValue(targetName, dialog.SelectedPath);
SetStatus($"已选择:{dialog.SelectedPath}", Brushes.Gray);
}
}
private string GetFileFilter(string targetName)
{
switch (targetName)
{
case nameof(StationsCsvFilePath):
return "CSV文件 (*.csv)|*.csv|所有文件 (*.*)|*.*";
case nameof(CadDwgFilePath):
return "DWG文件 (*.dwg)|*.dwg|所有文件 (*.*)|*.*";
case nameof(LocalSqLiteDb):
return "SQLite数据库 (*.db;*.sqlite;*.sqlite3)|*.db;*.sqlite;*.sqlite3|所有文件 (*.*)|*.*";
case nameof(WorkAreaFilePath):
case nameof(DwgJsonSetting):
case nameof(AlarmSetting):
case nameof(AlarmLevelConfig):
case nameof(ReportEventLevelSetting):
return "JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*";
default:
return "所有文件 (*.*)|*.*";
}
}
private string GetInitialDirectory(string currentPath, bool resourcesOnly)
{
if (resourcesOnly)
{
var resourceFilePath = ResolveAppRelativePath(currentPath);
if (!string.IsNullOrWhiteSpace(resourceFilePath) && File.Exists(resourceFilePath))
{
return Path.GetDirectoryName(resourceFilePath);
}
return GetResourcesDirectory();
}
if (!string.IsNullOrWhiteSpace(currentPath))
{
var path = ResolveAppRelativePath(currentPath);
if (Directory.Exists(path))
{
return path;
}
if (File.Exists(path))
{
return Path.GetDirectoryName(path);
}
}
return AppDomain.CurrentDomain.BaseDirectory;
}
private string ResolveAppRelativePath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
return null;
}
if (Path.IsPathRooted(path) && !path.StartsWith("\\", StringComparison.Ordinal))
{
return path;
}
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path.TrimStart('\\', '/'));
}
private string GetResourcesDirectory()
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ResourcesDirectoryName);
}
private bool TryGetResourcesRelativePath(string selectedFile, out string relativePath)
{
relativePath = null;
var resourcesDirectory = Path.GetFullPath(GetResourcesDirectory())
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;
var filePath = Path.GetFullPath(selectedFile);
if (!filePath.StartsWith(resourcesDirectory, StringComparison.OrdinalIgnoreCase))
{
return false;
}
var relativePart = filePath.Substring(resourcesDirectory.Length)
.Replace(Path.DirectorySeparatorChar, '\\')
.Replace(Path.AltDirectorySeparatorChar, '\\');
relativePath = ResourcesRelativePrefix + relativePart;
return true;
}
private string GetPathValue(string targetName)
{
switch (targetName)
{
case nameof(AlarmSetting):
return AlarmSetting;
case nameof(AlarmLevelConfig):
return AlarmLevelConfig;
case nameof(ReportEventLevelSetting):
return ReportEventLevelSetting;
case nameof(WorkAreaFilePath):
return WorkAreaFilePath;
case nameof(StationsCsvFilePath):
return StationsCsvFilePath;
case nameof(CadDwgFilePath):
return CadDwgFilePath;
case nameof(DwgJsonSetting):
return DwgJsonSetting;
case nameof(WavesMseedFilePath):
return WavesMseedFilePath;
case nameof(WavesTxtFilePath):
return WavesTxtFilePath;
case nameof(LocalSqLiteDb):
return LocalSqLiteDb;
case nameof(DwgSettings):
return DwgSettings;
case nameof(CadSettingsFileName):
return CadSettingsFileName;
default:
throw new InvalidOperationException($"未知的路径参数:{targetName}");
}
}
private void SetPathValue(string targetName, string value)
{
switch (targetName)
{
case nameof(AlarmSetting):
AlarmSetting = value;
break;
case nameof(AlarmLevelConfig):
AlarmLevelConfig = value;
break;
case nameof(ReportEventLevelSetting):
ReportEventLevelSetting = value;
break;
case nameof(WorkAreaFilePath):
WorkAreaFilePath = value;
break;
case nameof(StationsCsvFilePath):
StationsCsvFilePath = value;
break;
case nameof(CadDwgFilePath):
CadDwgFilePath = value;
break;
case nameof(DwgJsonSetting):
DwgJsonSetting = value;
break;
case nameof(WavesMseedFilePath):
WavesMseedFilePath = value;
break;
case nameof(WavesTxtFilePath):
WavesTxtFilePath = value;
break;
case nameof(LocalSqLiteDb):
LocalSqLiteDb = value;
break;
case nameof(DwgSettings):
DwgSettings = value;
break;
case nameof(CadSettingsFileName):
CadSettingsFileName = value;
break;
default:
throw new InvalidOperationException($"未知的路径参数:{targetName}");
}
RaisePropertyChanged(targetName);
}
private bool ShouldReloadWarningData(BusinessConfig previousConfig, BusinessConfig savedConfig)
{
if (previousConfig?.Runtime == null || savedConfig?.Runtime == null)
{
return false;
}
return previousConfig.Runtime.DataLookbackHours != savedConfig.Runtime.DataLookbackHours;
}
private void Load(BusinessConfig config)
{
ApiDomain = config.Endpoints.ApiDomain;
AlarmSetting = config.Paths.AlarmSetting;
AlarmLevelConfig = config.Paths.AlarmLevelConfig;
ReportEventLevelSetting = config.Paths.ReportEventLevelSetting;
WorkAreaFilePath = config.Paths.WorkAreaFilePath;
StationsCsvFilePath = config.Paths.StationsCsvFilePath;
CadDwgFilePath = config.Paths.CadDwgFilePath;
DwgJsonSetting = config.Paths.DwgJsonSetting;
WavesMseedFilePath = config.Paths.WavesMseedFilePath;
WavesTxtFilePath = config.Paths.WavesTxtFilePath;
LocalSqLiteDb = config.Paths.LocalSqLiteDb;
DwgSettings = config.Paths.DwgSettings;
CadSettingsFileName = config.Paths.CadSettingsFileName;
IsDesign = config.Runtime.IsDesign;
IsRealtime = config.Runtime.IsRealtime;
RefreshInterval = config.Runtime.RefreshInterval.ToString(CultureInfo.InvariantCulture);
DataLookbackHours = config.Runtime.DataLookbackHours.ToString("0.##", CultureInfo.InvariantCulture);
DataCacheTimeLenMins = config.Runtime.DataCacheTimeLenMins.ToString(CultureInfo.InvariantCulture);
TencentMySql = GetConnection(config, "TencetnMySQL");
RealtimeResultTable = config.Database.Tables.RealtimeResultTable;
RealtimeWaveDataTable = config.Database.Tables.RealtimeWaveDataTable;
RealtimeFocalmechanismTable = config.Database.Tables.RealtimeFocalmechanismTable;
PostResultTable = config.Database.Tables.PostResultTable;
PostWaveDataTable = config.Database.Tables.PostWaveDataTable;
PostFocalmechanismTable = config.Database.Tables.PostFocalmechanismTable;
CommpanyName = config.Branding.CommpanyName;
SystemNameCn = config.Branding.SystemNameCn;
SystemNameEn = config.Branding.SystemNameEn;
WorkAreaName = config.Branding.WorkAreaName;
SystemShortName = config.Branding.SystemShortName;
DailyReportStartTime = config.Report.DailyReportStartTime;
DailyReportPlanOffsetX = config.Report.DailyReportPlanOffsetX.ToString(CultureInfo.InvariantCulture);
DailyReportPlanOffsetY = config.Report.DailyReportPlanOffsetY.ToString(CultureInfo.InvariantCulture);
BaseX = config.Coordinates.BaseX.ToString(CultureInfo.InvariantCulture);
BaseY = config.Coordinates.BaseY.ToString(CultureInfo.InvariantCulture);
BaseZ = config.Coordinates.BaseZ.ToString(CultureInfo.InvariantCulture);
RaiseAllSettingPropertiesChanged();
}
private BusinessConfig BuildConfig(BusinessConfig currentConfig)
{
DateTime.Parse(Require(DailyReportStartTime, "日报起始时间"));
var dataLookbackHours = ParseDouble(DataLookbackHours, "数据时长");
DataCacheTimeLenMins = ((int)Math.Round(dataLookbackHours * 60.0)).ToString(CultureInfo.InvariantCulture);
var endpointSettings = BuildEndpointSettings(currentConfig);
var databaseSettings = BuildDatabaseSettings(currentConfig);
return new BusinessConfig
{
Endpoints = endpointSettings,
Paths = new PathSettings
{
AlarmSetting = Require(AlarmSetting, "报警配置"),
AlarmLevelConfig = Require(AlarmLevelConfig, "报警等级配置"),
ReportEventLevelSetting = Require(ReportEventLevelSetting, "报表事件分级"),
WorkAreaFilePath = Require(WorkAreaFilePath, "工区配置"),
StationsCsvFilePath = Require(StationsCsvFilePath, "台站CSV"),
CadDwgFilePath = Require(CadDwgFilePath, "CAD DWG"),
DwgJsonSetting = Require(DwgJsonSetting, "DWG图层设置"),
WavesMseedFilePath = Require(WavesMseedFilePath, "Mseed缓存目录"),
WavesTxtFilePath = Require(WavesTxtFilePath, "Txt缓存目录"),
LocalSqLiteDb = CanEditAdvancedSettings ? Require(LocalSqLiteDb, "本地 SQLite") : currentConfig.Paths.LocalSqLiteDb,
DwgSettings = CanEditAdvancedSettings ? EmptyToNull(DwgSettings) : currentConfig.Paths.DwgSettings,
CadSettingsFileName = CanEditAdvancedSettings ? EmptyToNull(CadSettingsFileName) : currentConfig.Paths.CadSettingsFileName
},
Runtime = new RuntimeSettings
{
IsDesign = CanEditAdvancedSettings ? IsDesign : currentConfig.Runtime.IsDesign,
IsRealtime = CanEditAdvancedSettings ? IsRealtime : currentConfig.Runtime.IsRealtime,
RefreshInterval = ParseInt(RefreshInterval, "刷新间隔"),
DataLookbackHours = dataLookbackHours,
DataCacheTimeLenMins = ParseInt(DataCacheTimeLenMins, "数据缓存时长")
},
Database = databaseSettings,
Branding = new BrandingSettings
{
CommpanyName = Require(CommpanyName, "公司名称"),
SystemNameCn = Require(SystemNameCn, "系统中文名"),
SystemNameEn = Require(SystemNameEn, "系统英文名"),
WorkAreaName = Require(WorkAreaName, "工区名称"),
SystemShortName = Require(SystemShortName, "系统简称")
},
Report = new ReportSettings
{
DailyReportStartTime = DailyReportStartTime.Trim(),
DailyReportPlanOffsetX = ParseDouble(DailyReportPlanOffsetX, "平面图横向偏移"),
DailyReportPlanOffsetY = ParseDouble(DailyReportPlanOffsetY, "平面图纵向偏移")
},
Coordinates = new CoordinateSettings
{
BaseX = ParseDouble(BaseX, "BaseX"),
BaseY = ParseDouble(BaseY, "BaseY"),
BaseZ = ParseDouble(BaseZ, "BaseZ")
}
};
}
private EndpointSettings BuildEndpointSettings(BusinessConfig currentConfig)
{
return new EndpointSettings
{
ApiDomain = CanEditAdvancedSettings ? Require(ApiDomain, "API 域名") : currentConfig.Endpoints.ApiDomain
};
}
private DatabaseSettings BuildDatabaseSettings(BusinessConfig currentConfig)
{
if (!CanEditAdvancedSettings)
{
return new DatabaseSettings
{
Connections = new Dictionary<string, string>
{
{ "TencetnMySQL", GetConnection(currentConfig, "TencetnMySQL") }
},
Tables = CopyTableSettings(currentConfig.Database.Tables)
};
}
return new DatabaseSettings
{
Connections = new Dictionary<string, string>
{
{ "TencetnMySQL", Require(TencentMySql, "腾讯 MySQL") }
},
Tables = new TableSettings
{
RealtimeResultTable = Require(RealtimeResultTable, "实时结果表"),
RealtimeWaveDataTable = Require(RealtimeWaveDataTable, "实时波形表"),
RealtimeFocalmechanismTable = Require(RealtimeFocalmechanismTable, "实时震源机制表"),
PostResultTable = Require(PostResultTable, "后处理结果表"),
PostWaveDataTable = Require(PostWaveDataTable, "后处理波形表"),
PostFocalmechanismTable = Require(PostFocalmechanismTable, "后处理震源机制表")
}
};
}
private TableSettings CopyTableSettings(TableSettings source)
{
return new TableSettings
{
RealtimeResultTable = source.RealtimeResultTable,
RealtimeWaveDataTable = source.RealtimeWaveDataTable,
RealtimeFocalmechanismTable = source.RealtimeFocalmechanismTable,
PostResultTable = source.PostResultTable,
PostWaveDataTable = source.PostWaveDataTable,
PostFocalmechanismTable = source.PostFocalmechanismTable
};
}
private string GetConnection(BusinessConfig config, string name)
{
if (config.Database.Connections != null && config.Database.Connections.TryGetValue(name, out var value))
{
return value;
}
return string.Empty;
}
private bool HasAdvancedSettingsPermission()
{
var menus = GlobalData.CurrentUserInfo?.Menus;
if (menus == null)
{
return false;
}
return ContainsTargetView(menus, AdvancedSettingsTargetView) ||
AdvancedSettingsFallbackTargetViews.Any(targetView => ContainsTargetView(menus, targetView));
}
private bool ContainsTargetView(IEnumerable<MenuEntity> menus, string targetView)
{
return menus.Any(menu => string.Equals(menu.TargetView, targetView, StringComparison.OrdinalIgnoreCase));
}
private string Require(string value, string name)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new InvalidOperationException($"{name}不能为空");
}
return value.Trim();
}
private string EmptyToNull(string value)
{
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}
private int ParseInt(string value, string name)
{
if (!int.TryParse(Require(value, name), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
{
throw new InvalidOperationException($"{name}必须是整数");
}
return result;
}
private double ParseDouble(string value, string name)
{
if (!double.TryParse(Require(value, name), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
throw new InvalidOperationException($"{name}必须是数字");
}
return result;
}
private void SetStatus(string message, Brush brush)
{
StatusMessage = message;
StatusBrush = brush;
}
private void RaiseAllSettingPropertiesChanged()
{
RaisePropertyChanged(nameof(ApiDomain));
RaisePropertyChanged(nameof(AlarmSetting));
RaisePropertyChanged(nameof(AlarmLevelConfig));
RaisePropertyChanged(nameof(ReportEventLevelSetting));
RaisePropertyChanged(nameof(WorkAreaFilePath));
RaisePropertyChanged(nameof(StationsCsvFilePath));
RaisePropertyChanged(nameof(CadDwgFilePath));
RaisePropertyChanged(nameof(DwgJsonSetting));
RaisePropertyChanged(nameof(WavesMseedFilePath));
RaisePropertyChanged(nameof(WavesTxtFilePath));
RaisePropertyChanged(nameof(LocalSqLiteDb));
RaisePropertyChanged(nameof(DwgSettings));
RaisePropertyChanged(nameof(CadSettingsFileName));
RaisePropertyChanged(nameof(IsDesign));
RaisePropertyChanged(nameof(IsRealtime));
RaisePropertyChanged(nameof(RefreshInterval));
RaisePropertyChanged(nameof(DataLookbackHours));
RaisePropertyChanged(nameof(DataCacheTimeLenMins));
RaisePropertyChanged(nameof(TencentMySql));
RaisePropertyChanged(nameof(RealtimeResultTable));
RaisePropertyChanged(nameof(RealtimeWaveDataTable));
RaisePropertyChanged(nameof(RealtimeFocalmechanismTable));
RaisePropertyChanged(nameof(PostResultTable));
RaisePropertyChanged(nameof(PostWaveDataTable));
RaisePropertyChanged(nameof(PostFocalmechanismTable));
RaisePropertyChanged(nameof(CommpanyName));
RaisePropertyChanged(nameof(SystemNameCn));
RaisePropertyChanged(nameof(SystemNameEn));
RaisePropertyChanged(nameof(WorkAreaName));
RaisePropertyChanged(nameof(SystemShortName));
RaisePropertyChanged(nameof(DailyReportStartTime));
RaisePropertyChanged(nameof(DailyReportPlanOffsetX));
RaisePropertyChanged(nameof(DailyReportPlanOffsetY));
RaisePropertyChanged(nameof(BaseX));
RaisePropertyChanged(nameof(BaseY));
RaisePropertyChanged(nameof(BaseZ));
}
}
}