Refactor code to decouple view and viewmodel

pull/5550/head
2dust 2024-08-10 10:02:00 +08:00
parent d893ee4829
commit 8ff04dca0d
33 changed files with 248 additions and 161 deletions

View File

@ -1,9 +1,9 @@
<Application <Application
x:Class="v2rayN.App" x:Class="v2rayN.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
ShutdownMode="OnExplicitShutdown" ShutdownMode="OnExplicitShutdown"
StartupUri="Views/MainWindow.xaml"> StartupUri="Views/MainWindow.xaml">
<Application.Resources> <Application.Resources>

View File

@ -0,0 +1,14 @@
using ReactiveUI;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
namespace v2rayN.Base
{
public class MyReactiveObject : ReactiveObject
{
protected static Config? _config;
protected Func<EViewAction, bool>? _updateView;
protected NoticeHandler? _noticeHandler;
}
}

View File

@ -3,6 +3,9 @@
public enum EViewAction public enum EViewAction
{ {
AdjustMainLvColWidth, AdjustMainLvColWidth,
ProfilesFocus ProfilesFocus,
CloseWindow,
ShowYesNo,
AddBatchRoutingRulesYesNo,
} }
} }

View File

@ -1,22 +1,18 @@
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using ReactiveUI.Validation.Helpers;
using Splat; using Splat;
using System.IO; using System.IO;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class AddServer2ViewModel : ReactiveValidationObject public class AddServer2ViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive] [Reactive]
public ProfileItem SelectedSource { get; set; } public ProfileItem SelectedSource { get; set; }
@ -25,10 +21,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveServerCmd { get; } public ReactiveCommand<Unit, Unit> SaveServerCmd { get; }
public bool IsModified { get; set; } public bool IsModified { get; set; }
public AddServer2ViewModel(ProfileItem profileItem, Window view) public AddServer2ViewModel(ProfileItem profileItem, Func<EViewAction, bool>? updateView)
{ {
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_updateView = updateView;
if (profileItem.indexId.IsNullOrEmpty()) if (profileItem.indexId.IsNullOrEmpty())
{ {
@ -39,8 +36,6 @@ namespace v2rayN.ViewModels
SelectedSource = JsonUtils.DeepCopy(profileItem); SelectedSource = JsonUtils.DeepCopy(profileItem);
} }
_view = view;
BrowseServerCmd = ReactiveCommand.Create(() => BrowseServerCmd = ReactiveCommand.Create(() =>
{ {
BrowseServer(); BrowseServer();
@ -55,8 +50,6 @@ namespace v2rayN.ViewModels
{ {
SaveServer(); SaveServer();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
private void SaveServer() private void SaveServer()
@ -91,7 +84,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.EditCustomServer(_config, item) == 0) if (ConfigHandler.EditCustomServer(_config, item) == 0)
{ {
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
} }
else else
{ {

View File

@ -2,7 +2,7 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
@ -10,22 +10,18 @@ using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class AddServerViewModel : ReactiveObject public class AddServerViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive] [Reactive]
public ProfileItem SelectedSource { get; set; } public ProfileItem SelectedSource { get; set; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public AddServerViewModel(ProfileItem profileItem, Window view) public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
if (profileItem.id.IsNullOrEmpty()) if (profileItem.id.IsNullOrEmpty())
{ {
@ -44,8 +40,6 @@ namespace v2rayN.ViewModels
{ {
SaveServer(); SaveServer();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
private void SaveServer() private void SaveServer()
@ -141,8 +135,7 @@ namespace v2rayN.ViewModels
if (ret == 0) if (ret == 0)
{ {
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
//_view?.Close();
} }
else else
{ {

View File

@ -5,16 +5,15 @@ using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Windows; using System.Windows;
using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class ClashConnectionsViewModel : ReactiveObject public class ClashConnectionsViewModel : MyReactiveObject
{ {
private static Config _config;
private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>(); private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>();
public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems; public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems;

View File

@ -6,6 +6,7 @@ using Splat;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Windows; using System.Windows;
using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
@ -15,10 +16,8 @@ using static v2rayN.Models.ClashProxies;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class ClashProxiesViewModel : ReactiveObject public class ClashProxiesViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Dictionary<String, ProxiesItem>? proxies; private Dictionary<String, ProxiesItem>? proxies;
private Dictionary<String, ProvidersItem>? providers; private Dictionary<String, ProvidersItem>? providers;
private int delayTimeout = 99999999; private int delayTimeout = 99999999;

View File

@ -2,7 +2,7 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
@ -10,12 +10,8 @@ using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class DNSSettingViewModel : ReactiveObject public class DNSSettingViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive] public bool useSystemHosts { get; set; } [Reactive] public bool useSystemHosts { get; set; }
[Reactive] public string domainStrategy4Freedom { get; set; } [Reactive] public string domainStrategy4Freedom { get; set; }
[Reactive] public string domainDNSAddress { get; set; } [Reactive] public string domainDNSAddress { get; set; }
@ -30,11 +26,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; } public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; } public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }
public DNSSettingViewModel(Window view) public DNSSettingViewModel(Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray); var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
useSystemHosts = item.useSystemHosts; useSystemHosts = item.useSystemHosts;
@ -63,8 +59,6 @@ namespace v2rayN.ViewModels
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName); tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
private void SaveSetting() private void SaveSetting()
@ -114,11 +108,11 @@ namespace v2rayN.ViewModels
item2.domainStrategy4Freedom = domainStrategy4Freedom2; item2.domainStrategy4Freedom = domainStrategy4Freedom2;
item2.domainDNSAddress = domainDNSAddress2; item2.domainDNSAddress = domainDNSAddress2;
item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2)); item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2));; item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ;
ConfigHandler.SaveDNSItems(_config, item2); ConfigHandler.SaveDNSItems(_config, item2);
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
} }
} }
} }

View File

@ -11,6 +11,7 @@ using System.Reactive.Linq;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Handler.Statistics; using v2rayN.Handler.Statistics;
@ -20,14 +21,12 @@ using v2rayN.Views;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class MainWindowViewModel : ReactiveObject public class MainWindowViewModel : MyReactiveObject
{ {
#region private prop #region private prop
private CoreHandler _coreHandler; private CoreHandler _coreHandler;
private static Config _config;
private NoticeHandler? _noticeHandler;
private Action<EViewAction> _updateView;
private bool _showInTaskbar; private bool _showInTaskbar;
#endregion private prop #endregion private prop
@ -171,15 +170,14 @@ namespace v2rayN.ViewModels
#region Init #region Init
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Action<EViewAction> updateView) public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Func<EViewAction, bool>? updateView)
{ {
_updateView = updateView;
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
_noticeHandler = new NoticeHandler(snackbarMessageQueue);
Locator.CurrentMutable.RegisterLazySingleton(() => _noticeHandler, typeof(NoticeHandler));
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_updateView = updateView;
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
Locator.CurrentMutable.RegisterLazySingleton(() => _noticeHandler, typeof(NoticeHandler));
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz()); MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
SelectedRouting = new(); SelectedRouting = new();

View File

@ -2,7 +2,7 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
@ -10,12 +10,8 @@ using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class OptionSettingViewModel : ReactiveObject public class OptionSettingViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
#region Core #region Core
[Reactive] public int localPort { get; set; } [Reactive] public int localPort { get; set; }
@ -109,11 +105,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public OptionSettingViewModel(Window view) public OptionSettingViewModel(Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
#region Core #region Core
@ -201,8 +197,6 @@ namespace v2rayN.ViewModels
{ {
SaveSetting(); SaveSetting();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
private void InitCoreType() private void InitCoreType()
@ -365,7 +359,7 @@ namespace v2rayN.ViewModels
{ {
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
} }
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
} }
else else
{ {

View File

@ -8,6 +8,7 @@ using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Handler.Fmt; using v2rayN.Handler.Fmt;
@ -18,16 +19,14 @@ using v2rayN.Views;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class ProfilesViewModel : ReactiveObject public class ProfilesViewModel : MyReactiveObject
{ {
#region private prop #region private prop
private List<ProfileItem> _lstProfile; private List<ProfileItem> _lstProfile;
private string _serverFilter = string.Empty; private string _serverFilter = string.Empty;
private static Config _config;
private NoticeHandler? _noticeHandler;
private Dictionary<string, bool> _dicHeaderSort = new(); private Dictionary<string, bool> _dicHeaderSort = new();
private Action<EViewAction> _updateView;
#endregion private prop #endregion private prop
@ -103,12 +102,12 @@ namespace v2rayN.ViewModels
#region Init #region Init
public ProfilesViewModel(Action<EViewAction> updateView) public ProfilesViewModel(Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_updateView = updateView; _updateView = updateView;
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz()); MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
SelectedProfile = new(); SelectedProfile = new();
@ -507,8 +506,7 @@ namespace v2rayN.ViewModels
{ {
return; return;
} }
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
{ {
return; return;
} }

View File

@ -2,19 +2,16 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class RoutingRuleDetailsViewModel : ReactiveObject public class RoutingRuleDetailsViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
public IList<string> ProtocolItems { get; set; } public IList<string> ProtocolItems { get; set; }
public IList<string> InboundTagItems { get; set; } public IList<string> InboundTagItems { get; set; }
@ -35,11 +32,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view) public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
if (rulesItem.id.IsNullOrEmpty()) if (rulesItem.id.IsNullOrEmpty())
{ {
@ -61,8 +58,6 @@ namespace v2rayN.ViewModels
{ {
SaveRules(); SaveRules();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
private void SaveRules() private void SaveRules()
@ -98,7 +93,7 @@ namespace v2rayN.ViewModels
return; return;
} }
//_noticeHandler?.Enqueue(ResUI.OperationSuccess); //_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
} }
} }
} }

View File

@ -3,7 +3,7 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
@ -13,11 +13,8 @@ using Application = System.Windows.Application;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class RoutingRuleSettingViewModel : ReactiveObject public class RoutingRuleSettingViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
private List<RulesItem> _rules; private List<RulesItem> _rules;
[Reactive] [Reactive]
@ -44,11 +41,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public RoutingRuleSettingViewModel(RoutingItem routingItem, Window view) public RoutingRuleSettingViewModel(RoutingItem routingItem, Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
SelectedSource = new(); SelectedSource = new();
if (routingItem.id.IsNullOrEmpty()) if (routingItem.id.IsNullOrEmpty())
@ -115,8 +112,6 @@ namespace v2rayN.ViewModels
{ {
SaveRouting(); SaveRouting();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
public void RefreshRulesItems() public void RefreshRulesItems()
@ -174,7 +169,7 @@ namespace v2rayN.ViewModels
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules); _noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
return; return;
} }
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No) if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{ {
return; return;
} }
@ -254,7 +249,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.SaveRoutingItem(_config, item) == 0) if (ConfigHandler.SaveRoutingItem(_config, item) == 0)
{ {
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
} }
else else
{ {
@ -323,7 +318,7 @@ namespace v2rayN.ViewModels
private int AddBatchRoutingRules(RoutingItem routingItem, string? clipboardData) private int AddBatchRoutingRules(RoutingItem routingItem, string? clipboardData)
{ {
bool blReplace = false; bool blReplace = false;
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No) if (_updateView?.Invoke(EViewAction.AddBatchRoutingRulesYesNo) == false)
{ {
blReplace = true; blReplace = true;
} }

View File

@ -3,7 +3,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
@ -11,11 +12,8 @@ using v2rayN.Views;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class RoutingSettingViewModel : ReactiveObject public class RoutingSettingViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
private RoutingItem _lockedItem; private RoutingItem _lockedItem;
private List<RulesItem> _lockedRules; private List<RulesItem> _lockedRules;
@ -73,11 +71,11 @@ namespace v2rayN.ViewModels
#endregion Reactive #endregion Reactive
public RoutingSettingViewModel(Window view) public RoutingSettingViewModel(Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
SelectedSource = new(); SelectedSource = new();
ConfigHandler.InitBuiltinRouting(_config); ConfigHandler.InitBuiltinRouting(_config);
@ -125,8 +123,6 @@ namespace v2rayN.ViewModels
{ {
SaveRouting(); SaveRouting();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
#region locked #region locked
@ -211,7 +207,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.SaveConfig(_config) == 0) if (ConfigHandler.SaveConfig(_config) == 0)
{ {
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
} }
else else
{ {
@ -263,7 +259,7 @@ namespace v2rayN.ViewModels
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules); _noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
return; return;
} }
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No) if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{ {
return; return;
} }

View File

@ -2,29 +2,26 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class SubEditViewModel : ReactiveObject public class SubEditViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive] [Reactive]
public SubItem SelectedSource { get; set; } public SubItem SelectedSource { get; set; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; } public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public SubEditViewModel(SubItem subItem, Window view) public SubEditViewModel(SubItem subItem, Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view; _updateView = updateView;
if (subItem.id.IsNullOrEmpty()) if (subItem.id.IsNullOrEmpty())
{ {
@ -39,8 +36,6 @@ namespace v2rayN.ViewModels
{ {
SaveSub(); SaveSub();
}); });
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
private void SaveSub() private void SaveSub()
@ -75,8 +70,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.AddSubItem(_config, item) == 0) if (ConfigHandler.AddSubItem(_config, item) == 0)
{ {
_noticeHandler?.Enqueue(ResUI.OperationSuccess); _noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true; _updateView?.Invoke(EViewAction.CloseWindow);
//_view?.Close();
} }
else else
{ {

View File

@ -5,7 +5,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Windows; using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
@ -13,11 +14,8 @@ using v2rayN.Views;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class SubSettingViewModel : ReactiveObject public class SubSettingViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private IObservableCollection<SubItem> _subItems = new ObservableCollectionExtended<SubItem>(); private IObservableCollection<SubItem> _subItems = new ObservableCollectionExtended<SubItem>();
public IObservableCollection<SubItem> SubItems => _subItems; public IObservableCollection<SubItem> SubItems => _subItems;
@ -32,10 +30,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SubShareCmd { get; } public ReactiveCommand<Unit, Unit> SubShareCmd { get; }
public bool IsModified { get; set; } public bool IsModified { get; set; }
public SubSettingViewModel(Window view) public SubSettingViewModel(Func<EViewAction, bool>? updateView)
{ {
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_updateView = updateView;
SelectedSource = new(); SelectedSource = new();
@ -61,8 +60,6 @@ namespace v2rayN.ViewModels
{ {
SubShare(); SubShare();
}, canEditRemove); }, canEditRemove);
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
} }
public void RefreshSubItems() public void RefreshSubItems()
@ -96,7 +93,7 @@ namespace v2rayN.ViewModels
private void DeleteSub() private void DeleteSub()
{ {
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No) if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{ {
return; return;
} }

View File

@ -8,16 +8,14 @@ using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Windows; using System.Windows;
using v2rayN.Base;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx; using v2rayN.Resx;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
public class ThemeSettingViewModel : ReactiveObject public class ThemeSettingViewModel : MyReactiveObject
{ {
private static Config _config;
private NoticeHandler? _noticeHandler;
private readonly PaletteHelper _paletteHelper = new(); private readonly PaletteHelper _paletteHelper = new();
[Reactive] [Reactive]

View File

@ -2,6 +2,7 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.ViewModels; using v2rayN.ViewModels;
@ -15,7 +16,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow; this.Owner = Application.Current.MainWindow;
this.Loaded += Window_Loaded; this.Loaded += Window_Loaded;
ViewModel = new AddServer2ViewModel(profileItem, this); ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType))) foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
{ {
@ -37,6 +38,17 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);
}); });
Utils.SetDarkBorder(this, LazyConfig.Instance.GetConfig().uiItem.followSystemTheme ? !Utils.IsLightTheme() : LazyConfig.Instance.GetConfig().uiItem.colorModeDark);
}
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
return true;
} }
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)

View File

@ -21,7 +21,7 @@ namespace v2rayN.Views
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged; cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged; cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
ViewModel = new AddServerViewModel(profileItem, this); ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
if (profileItem.configType == EConfigType.VLESS) if (profileItem.configType == EConfigType.VLESS)
{ {
@ -224,6 +224,15 @@ namespace v2rayN.Views
this.Title = $"{profileItem.configType}"; this.Title = $"{profileItem.configType}";
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
return true;
}
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
{ {
txtRemarks.Focus(); txtRemarks.Focus();

View File

@ -1,11 +1,11 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashConnectionsView" x:Class="v2rayN.Views.ClashConnectionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:v2rayN.Resx" xmlns:resx="clr-namespace:v2rayN.Resx"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:vms="clr-namespace:v2rayN.ViewModels"
d:DesignHeight="450" d:DesignHeight="450"

View File

@ -1,12 +1,12 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashProxiesView" x:Class="v2rayN.Views.ClashProxiesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converters="clr-namespace:v2rayN.Converters"
xmlns:resx="clr-namespace:v2rayN.Resx" xmlns:resx="clr-namespace:v2rayN.Resx"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:vms="clr-namespace:v2rayN.ViewModels"
d:DesignHeight="450" d:DesignHeight="450"

View File

@ -1,6 +1,7 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.ViewModels; using v2rayN.ViewModels;
@ -18,7 +19,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow; this.Owner = Application.Current.MainWindow;
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
ViewModel = new DNSSettingViewModel(this); ViewModel = new DNSSettingViewModel(UpdateViewHandler);
Global.DomainStrategy4Freedoms.ForEach(it => Global.DomainStrategy4Freedoms.ForEach(it =>
{ {
@ -55,6 +56,15 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
return true;
}
private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e) private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)
{ {
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject"); Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");

View File

@ -1,5 +1,4 @@
using MaterialDesignThemes.Wpf; using ReactiveUI;
using ReactiveUI;
using Splat; using Splat;
using System.ComponentModel; using System.ComponentModel;
using System.Reactive.Disposables; using System.Reactive.Disposables;

View File

@ -23,7 +23,7 @@ namespace v2rayN.Views
_config = LazyConfig.Instance.GetConfig(); _config = LazyConfig.Instance.GetConfig();
var lstFonts = GetFonts(Utils.GetFontsPath()); var lstFonts = GetFonts(Utils.GetFontsPath());
ViewModel = new OptionSettingViewModel(this); ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged; clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
Global.destOverrideProtocols.ForEach(it => Global.destOverrideProtocols.ForEach(it =>
@ -171,6 +171,15 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
return true;
}
private List<string> GetFonts(string path) private List<string> GetFonts(string path)
{ {
var lstFonts = new List<string>(); var lstFonts = new List<string>();

View File

@ -10,6 +10,7 @@ using v2rayN.Base;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels; using v2rayN.ViewModels;
using Point = System.Windows.Point; using Point = System.Windows.Point;
@ -96,7 +97,7 @@ namespace v2rayN.Views
StorageUI(); StorageUI();
} }
private void UpdateViewHandler(EViewAction action) private bool UpdateViewHandler(EViewAction action)
{ {
if (action == EViewAction.AdjustMainLvColWidth) if (action == EViewAction.AdjustMainLvColWidth)
{ {
@ -109,6 +110,15 @@ namespace v2rayN.Views
{ {
lstProfiles.Focus(); lstProfiles.Focus();
} }
else if (action == EViewAction.ShowYesNo)
{
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
{
return false;
}
}
return true;
} }
private void lstProfiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) private void lstProfiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)

View File

@ -1,6 +1,7 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.ViewModels; using v2rayN.ViewModels;
@ -17,7 +18,7 @@ namespace v2rayN.Views
clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged; clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged; clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, this); ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
cmbOutboundTag.Items.Add(Global.ProxyTag); cmbOutboundTag.Items.Add(Global.ProxyTag);
cmbOutboundTag.Items.Add(Global.DirectTag); cmbOutboundTag.Items.Add(Global.DirectTag);
cmbOutboundTag.Items.Add(Global.BlockTag); cmbOutboundTag.Items.Add(Global.BlockTag);
@ -61,6 +62,15 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
return true;
}
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
{ {
cmbOutboundTag.Focus(); cmbOutboundTag.Focus();

View File

@ -4,6 +4,7 @@ using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.Enums; using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels; using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
@ -20,7 +21,7 @@ namespace v2rayN.Views
lstRules.SelectionChanged += lstRules_SelectionChanged; lstRules.SelectionChanged += lstRules_SelectionChanged;
lstRules.MouseDoubleClick += LstRules_MouseDoubleClick; lstRules.MouseDoubleClick += LstRules_MouseDoubleClick;
ViewModel = new RoutingRuleSettingViewModel(routingItem, this); ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
Global.DomainStrategies.ForEach(it => Global.DomainStrategies.ForEach(it =>
{ {
cmbdomainStrategy.Items.Add(it); cmbdomainStrategy.Items.Add(it);
@ -62,6 +63,30 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
else if (action == EViewAction.ShowYesNo)
{
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
{
return false;
}
}
else if (action == EViewAction.AddBatchRoutingRulesYesNo)
{
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)
{
return false;
}
}
return true;
}
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
{ {
txtRemarks.Focus(); txtRemarks.Focus();

View File

@ -2,7 +2,9 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels; using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
@ -19,7 +21,7 @@ namespace v2rayN.Views
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged; lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick; lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
ViewModel = new RoutingSettingViewModel(this); ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
Global.DomainStrategies.ForEach(it => Global.DomainStrategies.ForEach(it =>
{ {
@ -68,6 +70,22 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
else if (action == EViewAction.ShowYesNo)
{
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
{
return false;
}
}
return true;
}
private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e) private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
{ {
if (ViewModel?.IsModified == true) if (ViewModel?.IsModified == true)

View File

@ -1,6 +1,7 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.ViewModels; using v2rayN.ViewModels;
@ -15,7 +16,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow; this.Owner = Application.Current.MainWindow;
this.Loaded += Window_Loaded; this.Loaded += Window_Loaded;
ViewModel = new SubEditViewModel(subItem, this); ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
Global.SubConvertTargets.ForEach(it => Global.SubConvertTargets.ForEach(it =>
{ {
@ -40,6 +41,15 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
return true;
}
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
{ {
txtRemarks.Focus(); txtRemarks.Focus();

View File

@ -3,7 +3,9 @@ using System.ComponentModel;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.Enums;
using v2rayN.Models; using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels; using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
@ -16,7 +18,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow; this.Owner = Application.Current.MainWindow;
ViewModel = new SubSettingViewModel(this); ViewModel = new SubSettingViewModel(UpdateViewHandler);
this.Closing += SubSettingWindow_Closing; this.Closing += SubSettingWindow_Closing;
lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick; lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged; lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
@ -33,6 +35,22 @@ namespace v2rayN.Views
}); });
} }
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.CloseWindow)
{
this.DialogResult = true;
}
else if (action == EViewAction.ShowYesNo)
{
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
{
return false;
}
}
return true;
}
private void SubSettingWindow_Closing(object? sender, CancelEventArgs e) private void SubSettingWindow_Closing(object? sender, CancelEventArgs e)
{ {
if (ViewModel?.IsModified == true) if (ViewModel?.IsModified == true)

View File

@ -1,8 +1,5 @@
using ReactiveUI; using ReactiveUI;
using Splat;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows.Input;
using v2rayN.Handler;
using v2rayN.ViewModels; using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views