Compare commits

..

4 commits

Author SHA1 Message Date
JieXu
2beac97dc6
Merge bc1c42a2a2 into 06636d04ac 2025-08-17 13:33:36 +08:00
2dust
06636d04ac PacHandler is changed to singleton mode 2025-08-17 11:00:13 +08:00
DHR60
6979e21628
Remove DomainMatcher (#7781) 2025-08-17 09:32:02 +08:00
DHR60
310d266745
Add VLESS encryption support (#7782) 2025-08-17 09:15:06 +08:00
21 changed files with 51 additions and 130 deletions

View file

@ -305,13 +305,6 @@ public class Global
"" ""
]; ];
public static readonly List<string> DomainMatchers =
[
"linear",
"mph",
""
];
public static readonly List<string> Fingerprints = public static readonly List<string> Fingerprints =
[ [
"chrome", "chrome",

View file

@ -963,7 +963,7 @@ public class ConfigHandler
{ {
return -1; return -1;
} }
if (profileItem.Security.IsNotEmpty() && profileItem.Security != Global.None) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.Security = Global.None; profileItem.Security = Global.None;
} }

View file

@ -5,15 +5,18 @@ namespace ServiceLib.Handler;
public class PacHandler public class PacHandler
{ {
private static string _configPath; private static readonly Lazy<PacHandler> _instance = new(() => new PacHandler());
private static int _httpPort; public static PacHandler Instance => _instance.Value;
private static int _pacPort;
private static TcpListener? _tcpListener;
private static byte[] _writeContent;
private static bool _isRunning;
private static bool _needRestart = true;
public static async Task Start(string configPath, int httpPort, int pacPort) private string _configPath;
private int _httpPort;
private int _pacPort;
private TcpListener? _tcpListener;
private byte[] _writeContent;
private bool _isRunning;
private bool _needRestart = true;
public async Task StartAsync(string configPath, int httpPort, int pacPort)
{ {
_needRestart = configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning; _needRestart = configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning;
@ -30,7 +33,7 @@ public class PacHandler
} }
} }
private static async Task InitText() private async Task InitText()
{ {
var path = Path.Combine(_configPath, "pac.txt"); var path = Path.Combine(_configPath, "pac.txt");
@ -59,7 +62,7 @@ public class PacHandler
_writeContent = Encoding.UTF8.GetBytes(sb.ToString()); _writeContent = Encoding.UTF8.GetBytes(sb.ToString());
} }
private static void RunListener() private void RunListener()
{ {
_tcpListener = TcpListener.Create(_pacPort); _tcpListener = TcpListener.Create(_pacPort);
_isRunning = true; _isRunning = true;
@ -87,14 +90,14 @@ public class PacHandler
}, TaskCreationOptions.LongRunning); }, TaskCreationOptions.LongRunning);
} }
private static void WriteContent(TcpClient client) private void WriteContent(TcpClient client)
{ {
var stream = client.GetStream(); var stream = client.GetStream();
stream.Write(_writeContent, 0, _writeContent.Length); stream.Write(_writeContent, 0, _writeContent.Length);
stream.Flush(); stream.Flush();
} }
public static void Stop() public void Stop()
{ {
if (_tcpListener == null) if (_tcpListener == null)
{ {

View file

@ -56,7 +56,7 @@ public static class SysProxyHandler
if (type != ESysProxyType.Pac && Utils.IsWindows()) if (type != ESysProxyType.Pac && Utils.IsWindows())
{ {
PacHandler.Stop(); PacHandler.Instance.Stop();
} }
} }
catch (Exception ex) catch (Exception ex)
@ -91,7 +91,7 @@ public static class SysProxyHandler
private static async Task SetWindowsProxyPac(int port) private static async Task SetWindowsProxyPac(int port)
{ {
var portPac = AppHandler.Instance.GetLocalPort(EInboundProtocol.pac); var portPac = AppHandler.Instance.GetLocalPort(EInboundProtocol.pac);
await PacHandler.Start(Utils.GetConfigPath(), port, portPac); await PacHandler.Instance.StartAsync(Utils.GetConfigPath(), port, portPac);
var strProxy = $"{Global.HttpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}"; var strProxy = $"{Global.HttpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}";
ProxySettingWindows.SetProxy(strProxy, "", 4); ProxySettingWindows.SetProxy(strProxy, "", 4);
} }

View file

@ -165,7 +165,6 @@ public class RoutingBasicItem
{ {
public string DomainStrategy { get; set; } public string DomainStrategy { get; set; }
public string DomainStrategy4Singbox { get; set; } public string DomainStrategy4Singbox { get; set; }
public string DomainMatcher { get; set; }
public string RoutingIndexId { get; set; } public string RoutingIndexId { get; set; }
} }

View file

@ -233,8 +233,6 @@ public class Routing4Ray
{ {
public string domainStrategy { get; set; } public string domainStrategy { get; set; }
public string? domainMatcher { get; set; }
public List<RulesItem4Ray> rules { get; set; } public List<RulesItem4Ray> rules { get; set; }
public List<BalancersItem4Ray>? balancers { get; set; } public List<BalancersItem4Ray>? balancers { get; set; }

View file

@ -2463,15 +2463,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Domain Matcher 的本地化字符串。
/// </summary>
public static string TbdomainMatcher {
get {
return ResourceManager.GetString("TbdomainMatcher", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Domain strategy 的本地化字符串。 /// 查找类似 Domain strategy 的本地化字符串。
/// </summary> /// </summary>

View file

@ -825,9 +825,6 @@
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>تنظیم کردن به عنوان قانون فعال</value> <value>تنظیم کردن به عنوان قانون فعال</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve">
<value>تطبیق دامنه</value>
</data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>استراتژی دامنه</value> <value>استراتژی دامنه</value>
</data> </data>

View file

@ -825,9 +825,6 @@
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>Beállítás aktív szabályként (Enter)</value> <value>Beállítás aktív szabályként (Enter)</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve">
<value>Tartomány illesztő</value>
</data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Tartomány stratégia</value> <value>Tartomány stratégia</value>
</data> </data>

View file

@ -825,9 +825,6 @@
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>Set as active rule (Enter)</value> <value>Set as active rule (Enter)</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve">
<value>Domain Matcher</value>
</data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Domain strategy</value> <value>Domain strategy</value>
</data> </data>

View file

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
@ -825,9 +825,6 @@
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>Установить как активное правило</value> <value>Установить как активное правило</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve">
<value>Сопоставитель доменов</value>
</data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Доменная стратегия</value> <value>Доменная стратегия</value>
</data> </data>
@ -1500,4 +1497,4 @@
<data name="TbFullConfigTemplateDesc" xml:space="preserve"> <data name="TbFullConfigTemplateDesc" xml:space="preserve">
<value>Эта функция предназначена для продвинутых пользователей и особых случаев. После включения игнорируются базовые настройки ядра, DNS и маршрутизации. Вы должны самостоятельно корректно задать порт системного прокси, учёт трафика и другие связанные параметры — всё настраивается вручную.</value> <value>Эта функция предназначена для продвинутых пользователей и особых случаев. После включения игнорируются базовые настройки ядра, DNS и маршрутизации. Вы должны самостоятельно корректно задать порт системного прокси, учёт трафика и другие связанные параметры — всё настраивается вручную.</value>
</data> </data>
</root> </root>

View file

@ -825,9 +825,6 @@
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>设为活动规则 (Enter)</value> <value>设为活动规则 (Enter)</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve">
<value>域名匹配算法</value>
</data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>域名解析策略</value> <value>域名解析策略</value>
</data> </data>

View file

@ -825,9 +825,6 @@
<data name="menuRoutingAdvancedSetDefault" xml:space="preserve"> <data name="menuRoutingAdvancedSetDefault" xml:space="preserve">
<value>設為活動規則 (Enter)</value> <value>設為活動規則 (Enter)</value>
</data> </data>
<data name="TbdomainMatcher" xml:space="preserve">
<value>域名匹配演算法</value>
</data>
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>域名解析策略</value> <value>域名解析策略</value>
</data> </data>

View file

@ -523,7 +523,6 @@ public class CoreConfigV2rayService
if (v2rayConfig.routing?.rules != null) if (v2rayConfig.routing?.rules != null)
{ {
v2rayConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy; v2rayConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
v2rayConfig.routing.domainMatcher = _config.RoutingBasicItem.DomainMatcher.IsNullOrEmpty() ? null : _config.RoutingBasicItem.DomainMatcher;
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing != null) if (routing != null)

View file

@ -75,10 +75,7 @@ public class CheckUpdateViewModel : MyReactiveObject
private async Task CheckUpdate() private async Task CheckUpdate()
{ {
await Task.Run(async () => await Task.Run(CheckUpdateTask);
{
await CheckUpdateTask();
});
} }
private async Task CheckUpdateTask() private async Task CheckUpdateTask()

View file

@ -20,9 +20,6 @@ public class RoutingSettingViewModel : MyReactiveObject
[Reactive] [Reactive]
public string DomainStrategy { get; set; } public string DomainStrategy { get; set; }
[Reactive]
public string DomainMatcher { get; set; }
[Reactive] [Reactive]
public string DomainStrategy4Singbox { get; set; } public string DomainStrategy4Singbox { get; set; }
@ -75,7 +72,6 @@ public class RoutingSettingViewModel : MyReactiveObject
SelectedSource = new(); SelectedSource = new();
DomainStrategy = _config.RoutingBasicItem.DomainStrategy; DomainStrategy = _config.RoutingBasicItem.DomainStrategy;
DomainMatcher = _config.RoutingBasicItem.DomainMatcher;
DomainStrategy4Singbox = _config.RoutingBasicItem.DomainStrategy4Singbox; DomainStrategy4Singbox = _config.RoutingBasicItem.DomainStrategy4Singbox;
await ConfigHandler.InitBuiltinRouting(_config); await ConfigHandler.InitBuiltinRouting(_config);
@ -109,7 +105,6 @@ public class RoutingSettingViewModel : MyReactiveObject
private async Task SaveRoutingAsync() private async Task SaveRoutingAsync()
{ {
_config.RoutingBasicItem.DomainStrategy = DomainStrategy; _config.RoutingBasicItem.DomainStrategy = DomainStrategy;
_config.RoutingBasicItem.DomainMatcher = DomainMatcher;
_config.RoutingBasicItem.DomainStrategy4Singbox = DomainStrategy4Singbox; _config.RoutingBasicItem.DomainStrategy4Singbox = DomainStrategy4Singbox;
if (await ConfigHandler.SaveConfig(_config) == 0) if (await ConfigHandler.SaveConfig(_config) == 0)

View file

@ -334,10 +334,7 @@ public class StatusBarViewModel : MyReactiveObject
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, ResUI.Speedtesting); _updateView?.Invoke(EViewAction.DispatcherServerAvailability, ResUI.Speedtesting);
var msg = await Task.Run(async () => var msg = await Task.Run(ConnectionHandler.Instance.RunAvailabilityCheck);
{
return await ConnectionHandler.Instance.RunAvailabilityCheck();
});
NoticeHandler.Instance.SendMessageEx(msg); NoticeHandler.Instance.SendMessageEx(msg);
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg); _updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg);

View file

@ -50,7 +50,7 @@
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
ColumnDefinitions="Auto,Auto" ColumnDefinitions="Auto,Auto"
DockPanel.Dock="Top" DockPanel.Dock="Top"
RowDefinitions="Auto,Auto,Auto"> RowDefinitions="Auto,Auto">
<TextBlock <TextBlock
Grid.Row="0" Grid.Row="0"
@ -74,19 +74,6 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbdomainMatcher}" />
<ComboBox
x:Name="cmbdomainMatcher"
Grid.Row="1"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"> VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy4Singbox_Click"> <HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy4Singbox_Click">
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" /> <TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" />
@ -94,7 +81,7 @@
</TextBlock> </TextBlock>
<ComboBox <ComboBox
x:Name="cmbdomainStrategy4Singbox" x:Name="cmbdomainStrategy4Singbox"
Grid.Row="2" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="300" Width="300"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"

View file

@ -27,7 +27,6 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
ViewModel = new RoutingSettingViewModel(UpdateViewHandler); ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
cmbdomainStrategy.ItemsSource = Global.DomainStrategies; cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox; cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
this.WhenActivated(disposables => this.WhenActivated(disposables =>
@ -36,7 +35,6 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy, v => v.cmbdomainStrategy.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DomainStrategy, v => v.cmbdomainStrategy.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainMatcher, v => v.cmbdomainMatcher.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables);

View file

@ -78,7 +78,6 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
@ -109,21 +108,6 @@
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbdomainMatcher}" />
<ComboBox
x:Name="cmbdomainMatcher"
Grid.Row="1"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"> Style="{StaticResource ToolbarTextBlock}">
<Hyperlink Click="linkdomainStrategy4Singbox_Click"> <Hyperlink Click="linkdomainStrategy4Singbox_Click">
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" /> <TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" />
@ -132,7 +116,7 @@
</TextBlock> </TextBlock>
<ComboBox <ComboBox
x:Name="cmbdomainStrategy4Singbox" x:Name="cmbdomainStrategy4Singbox"
Grid.Row="2" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="300" Width="300"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"

View file

@ -22,7 +22,6 @@ public partial class RoutingSettingWindow
ViewModel = new RoutingSettingViewModel(UpdateViewHandler); ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
cmbdomainStrategy.ItemsSource = Global.DomainStrategies; cmbdomainStrategy.ItemsSource = Global.DomainStrategies;
cmbdomainMatcher.ItemsSource = Global.DomainMatchers;
cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox; cmbdomainStrategy4Singbox.ItemsSource = Global.DomainStrategies4Singbox;
this.WhenActivated(disposables => this.WhenActivated(disposables =>
@ -31,7 +30,6 @@ public partial class RoutingSettingWindow
this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DomainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainMatcher, v => v.cmbdomainMatcher.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables);