mirror of
https://github.com/2dust/v2rayN.git
synced 2026-02-28 21:23:04 +00:00
Compare commits
3 commits
3550c3c925
...
7a70f630ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a70f630ad | ||
|
|
ac43bb051d | ||
|
|
7b31bcdd9f |
21 changed files with 186 additions and 29 deletions
|
|
@ -254,6 +254,7 @@ public static class ConfigHandler
|
|||
item.CertSha = profileItem.CertSha;
|
||||
item.EchConfigList = profileItem.EchConfigList;
|
||||
item.EchForceQuery = profileItem.EchForceQuery;
|
||||
item.Finalmask = profileItem.Finalmask;
|
||||
item.ProtoExtra = profileItem.ProtoExtra;
|
||||
}
|
||||
|
||||
|
|
@ -1122,6 +1123,7 @@ public static class ConfigHandler
|
|||
&& AreEqual(o.Fingerprint, n.Fingerprint)
|
||||
&& AreEqual(o.PublicKey, n.PublicKey)
|
||||
&& AreEqual(o.ShortId, n.ShortId)
|
||||
&& AreEqual(o.Finalmask, n.Finalmask)
|
||||
&& (!remarks || o.Remarks == n.Remarks);
|
||||
|
||||
static bool AreEqual(string? a, string? b)
|
||||
|
|
|
|||
|
|
@ -99,7 +99,12 @@ public static class CoreConfigHandler
|
|||
var nodes = await AppManager.Instance.GetProfileItemsByIndexIds(ids);
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
await FillNodeContext(context, node, false);
|
||||
var actNode = await FillNodeContext(context, node, true);
|
||||
if (node.IndexId == actNode.IndexId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
context.ServerTestItemMap[node.IndexId] = actNode.IndexId;
|
||||
}
|
||||
if (coreType == ECoreType.sing_box)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,6 +73,19 @@ public class BaseFmt
|
|||
{
|
||||
dicQuery.Add("pcs", Utils.UrlEncode(item.CertSha));
|
||||
}
|
||||
if (item.Finalmask.IsNotEmpty())
|
||||
{
|
||||
var node = JsonUtils.ParseJson(item.Finalmask);
|
||||
var finalmask = node != null
|
||||
? JsonUtils.Serialize(node, new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = false,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
})
|
||||
: item.Finalmask;
|
||||
dicQuery.Add("fm", Utils.UrlEncode(finalmask));
|
||||
}
|
||||
|
||||
dicQuery.Add("type", item.Network.IsNotEmpty() ? item.Network : nameof(ETransport.tcp));
|
||||
|
||||
|
|
@ -214,6 +227,24 @@ public class BaseFmt
|
|||
item.EchConfigList = GetQueryDecoded(query, "ech");
|
||||
item.CertSha = GetQueryDecoded(query, "pcs");
|
||||
|
||||
var finalmaskDecoded = GetQueryDecoded(query, "fm");
|
||||
if (finalmaskDecoded.IsNotEmpty())
|
||||
{
|
||||
var node = JsonUtils.ParseJson(finalmaskDecoded);
|
||||
item.Finalmask = node != null
|
||||
? JsonUtils.Serialize(node, new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
})
|
||||
: finalmaskDecoded;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Finalmask = string.Empty;
|
||||
}
|
||||
|
||||
if (_allowInsecureArray.Any(k => GetQueryDecoded(query, k) == "1"))
|
||||
{
|
||||
item.AllowInsecure = Global.AllowInsecure.First();
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ public record CoreConfigContext
|
|||
public Config AppConfig { get; init; } = new();
|
||||
public FullConfigTemplateItem? FullConfigTemplate { get; init; } = new();
|
||||
|
||||
// Test ServerTestItem Map
|
||||
public Dictionary<string, string> ServerTestItemMap { get; init; } = new();
|
||||
|
||||
// TUN Compatibility
|
||||
public bool IsTunEnabled { get; init; } = false;
|
||||
public HashSet<string> ProtectDomainList { get; init; } = new();
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ public class ProfileItem
|
|||
public string CertSha { get; set; }
|
||||
public string EchConfigList { get; set; }
|
||||
public string EchForceQuery { get; set; }
|
||||
public string Finalmask { get; set; }
|
||||
|
||||
public string ProtoExtra { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ public class StreamSettings4Ray
|
|||
|
||||
public HysteriaSettings4Ray? hysteriaSettings { get; set; }
|
||||
|
||||
public FinalMask4Ray? finalmask { get; set; }
|
||||
public Finalmask4Ray? finalmask { get; set; }
|
||||
|
||||
public Sockopt4Ray? sockopt { get; set; }
|
||||
}
|
||||
|
|
@ -476,7 +476,7 @@ public class HysteriaUdpHop4Ray
|
|||
public string? interval { get; set; }
|
||||
}
|
||||
|
||||
public class FinalMask4Ray
|
||||
public class Finalmask4Ray
|
||||
{
|
||||
public List<Mask4Ray>? tcp { get; set; }
|
||||
public List<Mask4Ray>? udp { get; set; }
|
||||
|
|
@ -485,7 +485,7 @@ public class FinalMask4Ray
|
|||
public class Mask4Ray
|
||||
{
|
||||
public string type { get; set; }
|
||||
public MaskSettings4Ray? settings { get; set; }
|
||||
public object? settings { get; set; }
|
||||
}
|
||||
|
||||
public class MaskSettings4Ray
|
||||
|
|
|
|||
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
|
@ -2916,6 +2916,15 @@ namespace ServiceLib.Resx {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Finalmask 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbFinalmask {
|
||||
get {
|
||||
return ResourceManager.GetString("TbFinalmask", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fingerprint 的本地化字符串。
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>Configuration item preview</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1665,4 +1665,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>Configuration item preview</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>Configuration item preview</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>Configuration item preview</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>Configuration item preview</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1665,4 +1665,7 @@
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>子配置项预览</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1665,4 +1665,7 @@
|
|||
<data name="menuServerListPreview" xml:space="preserve">
|
||||
<value>Configuration item preview</value>
|
||||
</data>
|
||||
<data name="TbFinalmask" xml:space="preserve">
|
||||
<value>Finalmask</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -167,8 +167,9 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
var item = context.AllProxiesMap.GetValueOrDefault(it.IndexId);
|
||||
if (item is null || item.IsComplex() || !item.IsValid())
|
||||
var actIndexId = context.ServerTestItemMap.GetValueOrDefault(it.IndexId, it.IndexId);
|
||||
var item = context.AllProxiesMap.GetValueOrDefault(actIndexId);
|
||||
if (item is null || item.ConfigType is EConfigType.Custom || !item.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,8 +124,9 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
var item = context.AllProxiesMap.GetValueOrDefault(it.IndexId);
|
||||
if (item is null || item.IsComplex() || !item.IsValid())
|
||||
var actIndexId = context.ServerTestItemMap.GetValueOrDefault(it.IndexId, it.IndexId);
|
||||
var item = context.AllProxiesMap.GetValueOrDefault(actIndexId);
|
||||
if (item is null || item.ConfigType is EConfigType.Custom || !item.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -354,14 +354,7 @@ public partial class CoreConfigV2rayService
|
|||
var useragent = "";
|
||||
if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
useragent = Global.UserAgentTexts[_config.CoreBasicItem.DefUserAgent];
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
useragent = _config.CoreBasicItem.DefUserAgent;
|
||||
}
|
||||
useragent = Global.UserAgentTexts.GetValueOrDefault(_config.CoreBasicItem.DefUserAgent, _config.CoreBasicItem.DefUserAgent);
|
||||
}
|
||||
|
||||
//if tls
|
||||
|
|
@ -666,6 +659,11 @@ public partial class CoreConfigV2rayService
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_node.Finalmask.IsNullOrEmpty())
|
||||
{
|
||||
streamSettings.finalmask = JsonUtils.Deserialize<Finalmask4Ray>(_node.Finalmask);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
IsCancel="True" />
|
||||
</StackPanel>
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
|
||||
<Grid
|
||||
Grid.Row="0"
|
||||
|
|
@ -407,7 +407,7 @@
|
|||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbPorts7Tips}" />
|
||||
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
|
|
@ -420,7 +420,7 @@
|
|||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
|
|
@ -722,11 +722,51 @@
|
|||
Text="{x:Static resx:ResUI.TbPath}" />
|
||||
</Grid>
|
||||
|
||||
<Separator Grid.Row="5" Margin="{StaticResource MarginTb8}" />
|
||||
<Grid
|
||||
x:Name="gridFinalmask"
|
||||
Grid.Row="5"
|
||||
ColumnDefinitions="300,Auto">
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbFinalmask}" />
|
||||
<Button
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource MarginLr4}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Classes="IconButton">
|
||||
<Button.Content>
|
||||
<PathIcon Data="{StaticResource SemiIconMore}">
|
||||
<PathIcon.RenderTransform>
|
||||
<RotateTransform Angle="90" />
|
||||
</PathIcon.RenderTransform>
|
||||
</PathIcon>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBox
|
||||
x:Name="txtFinalmask"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
AcceptsReturn="True"
|
||||
Classes="TextArea"
|
||||
TextWrapping="NoWrap" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<Separator Grid.Row="6" Margin="{StaticResource MarginTb8}" />
|
||||
|
||||
<Grid
|
||||
x:Name="gridTls"
|
||||
Grid.Row="6"
|
||||
Grid.Row="7"
|
||||
ColumnDefinitions="300,Auto"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto">
|
||||
|
||||
|
|
@ -745,7 +785,7 @@
|
|||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridTlsMore"
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
ColumnDefinitions="300,Auto"
|
||||
IsVisible="False"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
|
|
@ -908,7 +948,7 @@
|
|||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridRealityMore"
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
ColumnDefinitions="300,Auto"
|
||||
IsVisible="False"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
|
|
@ -996,7 +1036,7 @@
|
|||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</Grid>
|
||||
<Separator Grid.Row="8" Margin="{StaticResource MarginTb8}" />
|
||||
<Separator Grid.Row="9" Margin="{StaticResource MarginTb8}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</DockPanel>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
|||
cmbCoreType.IsEnabled = false;
|
||||
cmbFingerprint.IsEnabled = false;
|
||||
cmbFingerprint.SelectedValue = string.Empty;
|
||||
gridFinalmask.IsVisible = false;
|
||||
|
||||
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
|
||||
break;
|
||||
|
|
@ -95,6 +96,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
|||
gridAnytls.IsVisible = true;
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbCoreType.IsEnabled = false;
|
||||
gridFinalmask.IsVisible = false;
|
||||
break;
|
||||
}
|
||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||
|
|
@ -194,6 +196,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
|||
this.Bind(ViewModel, vm => vm.SelectedSource.SpiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Mldsa65Verify, v => v.txtMldsa65Verify.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Finalmask, v => v.txtFinalmask.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.FetchCertCmd, v => v.btnFetchCert).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.FetchCertChainCmd, v => v.btnFetchCertChain).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@
|
|||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
|
|
@ -928,12 +930,47 @@
|
|||
Text="{x:Static resx:ResUI.TbPath}" />
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="gridFinalmask" Grid.Row="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbFinalmask}" />
|
||||
<materialDesign:PopupBox
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
StaysOpen="True"
|
||||
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
||||
<StackPanel>
|
||||
<TextBox
|
||||
x:Name="txtFinalmask"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
AcceptsReturn="True"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
MaxLines="8"
|
||||
MinLines="4"
|
||||
Style="{StaticResource MyOutlinedTextBox}"
|
||||
TextWrapping="NoWrap"
|
||||
VerticalScrollBarVisibility="Auto" />
|
||||
</StackPanel>
|
||||
</materialDesign:PopupBox>
|
||||
</Grid>
|
||||
|
||||
<Separator
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Margin="0,2"
|
||||
Style="{DynamicResource MaterialDesignSeparator}" />
|
||||
|
||||
<Grid x:Name="gridTls" Grid.Row="6">
|
||||
<Grid x:Name="gridTls" Grid.Row="7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
|
|
@ -963,7 +1000,7 @@
|
|||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridTlsMore"
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
Visibility="Hidden">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
|
@ -1152,7 +1189,7 @@
|
|||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridRealityMore"
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
Visibility="Hidden">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
|
@ -1264,7 +1301,7 @@
|
|||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Separator
|
||||
Grid.Row="8"
|
||||
Grid.Row="9"
|
||||
Margin="0,2"
|
||||
Style="{DynamicResource MaterialDesignSeparator}" />
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public partial class AddServerWindow
|
|||
cmbCoreType.IsEnabled = false;
|
||||
cmbFingerprint.IsEnabled = false;
|
||||
cmbFingerprint.Text = string.Empty;
|
||||
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||
|
||||
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
|
||||
break;
|
||||
|
|
@ -90,6 +91,7 @@ public partial class AddServerWindow
|
|||
gridAnytls.Visibility = Visibility.Visible;
|
||||
cmbCoreType.IsEnabled = false;
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
}
|
||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||
|
|
@ -190,6 +192,8 @@ public partial class AddServerWindow
|
|||
this.Bind(ViewModel, vm => vm.SelectedSource.SpiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Mldsa65Verify, v => v.txtMldsa65Verify.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Finalmask, v => v.txtFinalmask.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.FetchCertCmd, v => v.btnFetchCert).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.FetchCertChainCmd, v => v.btnFetchCertChain).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
|
|
|
|||
Loading…
Reference in a new issue