添加DataService为数据服务类,负责数据的加载工作,通过消息来通知DataService更新数据
This commit is contained in:
20
App.xaml.cs
20
App.xaml.cs
@@ -8,6 +8,7 @@ using NLog.Extensions.Logging;
|
|||||||
using PMSWPF.Data;
|
using PMSWPF.Data;
|
||||||
using PMSWPF.Data.Entities;
|
using PMSWPF.Data.Entities;
|
||||||
using PMSWPF.Data.Repositories;
|
using PMSWPF.Data.Repositories;
|
||||||
|
using PMSWPF.Enums;
|
||||||
using PMSWPF.Services;
|
using PMSWPF.Services;
|
||||||
using PMSWPF.ViewModels;
|
using PMSWPF.ViewModels;
|
||||||
using PMSWPF.Views;
|
using PMSWPF.Views;
|
||||||
@@ -34,6 +35,7 @@ public partial class App : Application
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
container.AddSingleton<DataServices>();
|
||||||
container.AddSingleton<NavgatorServices>();
|
container.AddSingleton<NavgatorServices>();
|
||||||
container.AddSingleton<IDialogService, DialogService>();
|
container.AddSingleton<IDialogService, DialogService>();
|
||||||
container.AddSingleton<GrowlNotificationService>();
|
container.AddSingleton<GrowlNotificationService>();
|
||||||
@@ -72,16 +74,18 @@ public partial class App : Application
|
|||||||
using (var db = DbContext.GetInstance())
|
using (var db = DbContext.GetInstance())
|
||||||
{
|
{
|
||||||
List<DbMenu> items = new List<DbMenu>();
|
List<DbMenu> items = new List<DbMenu>();
|
||||||
items.Add(new DbMenu() { Name = "主页", Icon = SegoeFluentIcons.Home.Glyph, ParentId = 0});
|
items.Add(new DbMenu()
|
||||||
items.Add(new DbMenu() { Name = "设备", Icon = SegoeFluentIcons.Devices.Glyph, ParentId = 0});
|
{ Name = "主页", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.Home.Glyph, ParentId = 0 });
|
||||||
items.Add(new DbMenu() { Name = "数据转换", Icon = SegoeFluentIcons.Move.Glyph, ParentId = 0});
|
items.Add(new DbMenu()
|
||||||
items.Add(new DbMenu() { Name = "设置", Icon = SegoeFluentIcons.Settings.Glyph, ParentId = 0});
|
{ Name = "设备", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.Devices3.Glyph, ParentId = 0 });
|
||||||
items.Add(new DbMenu() { Name = "关于", Icon = SegoeFluentIcons.Info.Glyph, ParentId = 0});
|
items.Add(new DbMenu()
|
||||||
|
{ Name = "数据转换", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.ChromeSwitch.Glyph, ParentId = 0 });
|
||||||
|
items.Add(new DbMenu()
|
||||||
|
{ Name = "设置", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.Settings.Glyph, ParentId = 0 });
|
||||||
|
items.Add(new DbMenu()
|
||||||
|
{ Name = "关于", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.Info.Glyph, ParentId = 0 });
|
||||||
db.Insertable<DbMenu>(items).ExecuteCommand();
|
db.Insertable<DbMenu>(items).ExecuteCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitDB()
|
private void InitDB()
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using PMSWPF.Enums;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using SqlSugar.DbConvert;
|
||||||
|
|
||||||
namespace PMSWPF.Data.Entities;
|
namespace PMSWPF.Data.Entities;
|
||||||
|
|
||||||
@@ -10,6 +12,8 @@ public class DbMenu
|
|||||||
public string Icon { get; set; }
|
public string Icon { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int ParentId { get; set; }
|
public int ParentId { get; set; }
|
||||||
|
[SugarColumn(ColumnDataType = "varchar(20)", SqlParameterDbType = typeof(EnumToStringConvert))]
|
||||||
|
public MenuType Type { get; set; }
|
||||||
|
|
||||||
[SugarColumn(IsIgnore = true)]
|
[SugarColumn(IsIgnore = true)]
|
||||||
public List<DbMenu> Items { get; set; }
|
public List<DbMenu> Items { get; set; }
|
||||||
|
|||||||
@@ -63,12 +63,14 @@ public class MenuRepository
|
|||||||
{
|
{
|
||||||
Name = "默认变量表",
|
Name = "默认变量表",
|
||||||
Icon = SegoeFluentIcons.Tablet.Glyph,
|
Icon = SegoeFluentIcons.Tablet.Glyph,
|
||||||
|
Type = MenuType.VariableTableMenu,
|
||||||
ParentId = addDM.Id,
|
ParentId = addDM.Id,
|
||||||
};
|
};
|
||||||
var addVarTable=new MenuBean()
|
var addVarTable=new MenuBean()
|
||||||
{
|
{
|
||||||
Name = "添加变量表",
|
Name = "添加变量表",
|
||||||
Icon = SegoeFluentIcons.Add.Glyph,
|
Icon = SegoeFluentIcons.Add.Glyph,
|
||||||
|
Type = MenuType.AddVariableTableMenu,
|
||||||
ParentId = addDM.Id,
|
ParentId = addDM.Id,
|
||||||
};
|
};
|
||||||
var defTableRes = await _db.Insertable<DbMenu>(defVarTable).ExecuteCommandAsync();
|
var defTableRes = await _db.Insertable<DbMenu>(defVarTable).ExecuteCommandAsync();
|
||||||
|
|||||||
8
Enums/LoadTypes.cs
Normal file
8
Enums/LoadTypes.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace PMSWPF.Enums;
|
||||||
|
|
||||||
|
public enum LoadTypes
|
||||||
|
{
|
||||||
|
Devices,
|
||||||
|
Menu,
|
||||||
|
Mqtt
|
||||||
|
}
|
||||||
9
Enums/MenuType.cs
Normal file
9
Enums/MenuType.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace PMSWPF.Enums;
|
||||||
|
|
||||||
|
public enum MenuType
|
||||||
|
{
|
||||||
|
MainMenu,
|
||||||
|
DeviceMenu,
|
||||||
|
VariableTableMenu,
|
||||||
|
AddVariableTableMenu,
|
||||||
|
}
|
||||||
@@ -14,4 +14,16 @@ public static class TaskExtensions
|
|||||||
onError?.Invoke(e);
|
onError?.Invoke(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static async Task Await<T>(this Task<T> task, Action<Exception> onError = null, Action<T> onComplete = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
T res= await task;
|
||||||
|
onComplete?.Invoke(res);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
onError?.Invoke(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
11
Message/LoadMessage.cs
Normal file
11
Message/LoadMessage.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||||
|
using PMSWPF.Enums;
|
||||||
|
|
||||||
|
namespace PMSWPF.Message;
|
||||||
|
|
||||||
|
public class LoadMessage:ValueChangedMessage<LoadTypes>
|
||||||
|
{
|
||||||
|
public LoadMessage(LoadTypes types) : base(types)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,9 @@ namespace PMSWPF.Message;
|
|||||||
|
|
||||||
public class NavgatorMessage : ValueChangedMessage<ViewModelBase>
|
public class NavgatorMessage : ValueChangedMessage<ViewModelBase>
|
||||||
{
|
{
|
||||||
public NavgatorMessage(ViewModelBase value) : base(value)
|
public Object Parameters;
|
||||||
|
public NavgatorMessage(ViewModelBase value,Object parameters=null) : base(value)
|
||||||
{
|
{
|
||||||
|
Parameters=parameters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using PMSWPF.Enums;
|
||||||
|
|
||||||
namespace PMSWPF.Models;
|
namespace PMSWPF.Models;
|
||||||
|
|
||||||
public class MenuBean
|
public class MenuBean
|
||||||
@@ -7,5 +9,7 @@ public class MenuBean
|
|||||||
public string Icon { get; set; }
|
public string Icon { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int ParentId { get; set; }
|
public int ParentId { get; set; }
|
||||||
|
|
||||||
|
public MenuType Type { get; set; }
|
||||||
public List<MenuBean> Items { get; set; }
|
public List<MenuBean> Items { get; set; }
|
||||||
}
|
}
|
||||||
76
Services/DataServices.cs
Normal file
76
Services/DataServices.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PMSWPF.Data.Repositories;
|
||||||
|
using PMSWPF.Enums;
|
||||||
|
using PMSWPF.Extensions;
|
||||||
|
using PMSWPF.Helper;
|
||||||
|
using PMSWPF.Message;
|
||||||
|
using PMSWPF.Models;
|
||||||
|
|
||||||
|
namespace PMSWPF.Services;
|
||||||
|
|
||||||
|
public partial class DataServices:ObservableRecipient,IRecipient<LoadMessage>
|
||||||
|
{
|
||||||
|
private readonly ILogger<DataServices> _logger;
|
||||||
|
[ObservableProperty]
|
||||||
|
private List<Device> _devices = new List<Device>();
|
||||||
|
[ObservableProperty]
|
||||||
|
private List<MenuBean> menuBeans = new List<MenuBean>();
|
||||||
|
private readonly DeviceRepository _deviceRepository;
|
||||||
|
private readonly MenuRepository _menuRepository;
|
||||||
|
|
||||||
|
public event Action<List<Device>> OnDeviceListChanged;
|
||||||
|
public event Action<List<MenuBean>> OnMenuListChanged;
|
||||||
|
|
||||||
|
|
||||||
|
partial void OnDevicesChanged(List<Device> devices)
|
||||||
|
{
|
||||||
|
OnDeviceListChanged?.Invoke(devices);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnMenuBeansChanged(List<MenuBean> menuBeans)
|
||||||
|
{
|
||||||
|
OnMenuListChanged?.Invoke(menuBeans);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DataServices(ILogger<DataServices> logger )
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
IsActive = true;
|
||||||
|
_deviceRepository = new DeviceRepository();
|
||||||
|
_menuRepository = new MenuRepository();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async void Receive(LoadMessage message)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!(message.Value is LoadTypes))
|
||||||
|
throw new ArgumentException($"接受到的加载类型错误:{message.Value}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
switch ((LoadTypes)message.Value )
|
||||||
|
{
|
||||||
|
case LoadTypes.Devices:
|
||||||
|
Devices= await _deviceRepository.GetAll();
|
||||||
|
break;
|
||||||
|
case LoadTypes.Menu:
|
||||||
|
MenuBeans= await _menuRepository.GetMenu();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
NotificationHelper.ShowMessage($"加载数据出现了错误:{e.Message}");
|
||||||
|
_logger.LogError($"加载数据出现了错误:{e.Message}");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ public class NavgatorServices : ObservableRecipient, IRecipient<NavgatorMessage>
|
|||||||
public void Receive(NavgatorMessage message)
|
public void Receive(NavgatorMessage message)
|
||||||
{
|
{
|
||||||
CurrentViewModel = message.Value;
|
CurrentViewModel = message.Value;
|
||||||
|
CurrentViewModel.NavgateParameters = message.Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public event Action OnViewModelChanged;
|
public event Action OnViewModelChanged;
|
||||||
|
|||||||
@@ -19,24 +19,27 @@ public partial class DevicesViewModel : ViewModelBase
|
|||||||
private readonly DeviceRepository _deviceRepository;
|
private readonly DeviceRepository _deviceRepository;
|
||||||
private readonly ILogger<DevicesViewModel> _logger;
|
private readonly ILogger<DevicesViewModel> _logger;
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
|
private readonly DataServices _dataServices;
|
||||||
|
|
||||||
[ObservableProperty] private ObservableCollection<Device> _devices;
|
[ObservableProperty] private ObservableCollection<Device> _devices;
|
||||||
private readonly MenuRepository _menuRepository;
|
private readonly MenuRepository _menuRepository;
|
||||||
|
|
||||||
public DevicesViewModel(
|
public DevicesViewModel(
|
||||||
ILogger<DevicesViewModel> logger, IDialogService dialogService
|
ILogger<DevicesViewModel> logger, IDialogService dialogService, DataServices dataServices
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_deviceRepository = new DeviceRepository();
|
_deviceRepository = new DeviceRepository();
|
||||||
_menuRepository = new MenuRepository();
|
_menuRepository = new MenuRepository();
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
|
_dataServices = dataServices;
|
||||||
|
|
||||||
|
WeakReferenceMessenger.Default.Send<LoadMessage>(new LoadMessage(LoadTypes.Devices));
|
||||||
|
_dataServices.OnDeviceListChanged += (devices) => { Devices = new ObservableCollection<Device>(devices); };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnLoadedAsync()
|
public async Task OnLoadedAsync()
|
||||||
{
|
{
|
||||||
var ds = await _deviceRepository.GetAll();
|
|
||||||
Devices = new ObservableCollection<Device>(ds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
@@ -56,6 +59,7 @@ public partial class DevicesViewModel : ViewModelBase
|
|||||||
MenuBean deviceMenu = new MenuBean()
|
MenuBean deviceMenu = new MenuBean()
|
||||||
{
|
{
|
||||||
Name = device.Name,
|
Name = device.Name,
|
||||||
|
Type = MenuType.DeviceMenu,
|
||||||
Icon = SegoeFluentIcons.Devices4.Glyph,
|
Icon = SegoeFluentIcons.Devices4.Glyph,
|
||||||
};
|
};
|
||||||
bool addMenuRes = await _menuRepository.AddDeviceMenu(deviceMenu);
|
bool addMenuRes = await _menuRepository.AddDeviceMenu(deviceMenu);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.Input;
|
|||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using PMSWPF.Data.Entities;
|
using PMSWPF.Data.Entities;
|
||||||
using PMSWPF.Data.Repositories;
|
using PMSWPF.Data.Repositories;
|
||||||
|
using PMSWPF.Enums;
|
||||||
using PMSWPF.Message;
|
using PMSWPF.Message;
|
||||||
using PMSWPF.Models;
|
using PMSWPF.Models;
|
||||||
using PMSWPF.Services;
|
using PMSWPF.Services;
|
||||||
@@ -13,6 +14,7 @@ namespace PMSWPF.ViewModels;
|
|||||||
public partial class MainViewModel : ViewModelBase
|
public partial class MainViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
private readonly NavgatorServices _navgatorServices;
|
private readonly NavgatorServices _navgatorServices;
|
||||||
|
private readonly DataServices _dataServices;
|
||||||
|
|
||||||
[ObservableProperty] private ViewModelBase currentViewModel;
|
[ObservableProperty] private ViewModelBase currentViewModel;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -20,32 +22,26 @@ public partial class MainViewModel : ViewModelBase
|
|||||||
|
|
||||||
private readonly MenuRepository _menuRepository;
|
private readonly MenuRepository _menuRepository;
|
||||||
|
|
||||||
public MainViewModel(NavgatorServices navgatorServices)
|
public MainViewModel(NavgatorServices navgatorServices,DataServices dataServices)
|
||||||
{
|
{
|
||||||
_navgatorServices = navgatorServices;
|
_navgatorServices = navgatorServices;
|
||||||
_menuRepository = new MenuRepository();
|
_dataServices = dataServices;
|
||||||
|
|
||||||
_navgatorServices.OnViewModelChanged += () => { CurrentViewModel = _navgatorServices.CurrentViewModel; };
|
_navgatorServices.OnViewModelChanged += () => { CurrentViewModel = _navgatorServices.CurrentViewModel; };
|
||||||
CurrentViewModel = new HomeViewModel();
|
CurrentViewModel = new HomeViewModel();
|
||||||
CurrentViewModel.OnLoaded();
|
CurrentViewModel.OnLoaded();
|
||||||
|
|
||||||
WeakReferenceMessenger.Default.Register<UpdateMenuMessage>( this,UpdateMenu);
|
WeakReferenceMessenger.Default.Send<LoadMessage>(new LoadMessage(LoadTypes.Menu));
|
||||||
|
dataServices.OnMenuListChanged += (menus) =>
|
||||||
}
|
|
||||||
|
|
||||||
private async void UpdateMenu(object recipient, UpdateMenuMessage message)
|
|
||||||
{
|
{
|
||||||
await LoadMenu();
|
Menus = new ObservableCollection<MenuBean>(menus);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override async void OnLoaded()
|
public override void OnLoaded()
|
||||||
{
|
{
|
||||||
await LoadMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadMenu()
|
|
||||||
{
|
|
||||||
var menuList= await _menuRepository.GetMenu();
|
|
||||||
Menus=new ObservableCollection<MenuBean>(menuList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@ namespace PMSWPF.ViewModels;
|
|||||||
|
|
||||||
public abstract class ViewModelBase : ObservableObject
|
public abstract class ViewModelBase : ObservableObject
|
||||||
{
|
{
|
||||||
|
public Object NavgateParameters { get; set; }
|
||||||
public abstract void OnLoaded();
|
public abstract void OnLoaded();
|
||||||
}
|
}
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
MenuItemsSource="{Binding Menus}"
|
MenuItemsSource="{Binding Menus}"
|
||||||
MenuItemTemplate="{StaticResource NavigationViewMenuItem}"
|
MenuItemTemplate="{StaticResource NavigationViewMenuItem}"
|
||||||
ItemInvoked="NavigationView_OnItemInvoked"
|
ItemInvoked="NavigationView_OnItemInvoked"
|
||||||
|
SelectionChanged="NavigationView_OnSelectionChanged"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- <ui:NavigationView.MenuItems> -->
|
<!-- <ui:NavigationView.MenuItems> -->
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using iNKORE.UI.WPF.Modern.Controls;
|
using iNKORE.UI.WPF.Modern.Controls;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using PMSWPF.Message;
|
using PMSWPF.Message;
|
||||||
|
using PMSWPF.Models;
|
||||||
using PMSWPF.ViewModels;
|
using PMSWPF.ViewModels;
|
||||||
|
|
||||||
namespace PMSWPF.Views;
|
namespace PMSWPF.Views;
|
||||||
@@ -69,6 +71,7 @@ public partial class MainView : Window
|
|||||||
private void NavigationView_OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
private void NavigationView_OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
||||||
{
|
{
|
||||||
ViewModelBase navgateVM = App.Current.Services.GetRequiredService<HomeViewModel>();
|
ViewModelBase navgateVM = App.Current.Services.GetRequiredService<HomeViewModel>();
|
||||||
|
Object parameter =null;
|
||||||
switch (args.InvokedItem)
|
switch (args.InvokedItem)
|
||||||
{
|
{
|
||||||
case "主页":
|
case "主页":
|
||||||
@@ -93,7 +96,13 @@ public partial class MainView : Window
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var nm = new NavgatorMessage(navgateVM);
|
var nm = new NavgatorMessage(navgateVM,parameter);
|
||||||
WeakReferenceMessenger.Default.Send(nm);
|
WeakReferenceMessenger.Default.Send(nm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void NavigationView_OnSelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||||
|
{
|
||||||
|
var selectMenu= args.SelectedItem as MenuBean;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,9 @@
|
|||||||
<ikw:SimpleStackPanel Orientation="Horizontal" Spacing="10">
|
<ikw:SimpleStackPanel Orientation="Horizontal" Spacing="10">
|
||||||
<TextBlock Text="所属设备:" /> <TextBlock Text="默认变量表" />
|
<TextBlock Text="所属设备:" /> <TextBlock Text="默认变量表" />
|
||||||
</ikw:SimpleStackPanel>
|
</ikw:SimpleStackPanel>
|
||||||
|
<DataGrid>
|
||||||
|
|
||||||
|
</DataGrid>
|
||||||
</ikw:SimpleStackPanel>
|
</ikw:SimpleStackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user