mirror of
				https://github.com/2dust/v2rayN.git
				synced 2025-10-27 10:40:08 +00:00 
			
		
		
		
	Compare commits
	
		
			17 commits
		
	
	
		
			71dcd8d1de
			...
			4ae34ccb01
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 4ae34ccb01 | ||
|   | 437b2bd4e6 | ||
|   | 81e4755dda | ||
|   | 9a78dcb61c | ||
|   | 5bf1b374bd | ||
|   | 5030269fdd | ||
|   | 02ba731442 | ||
|   | c81b89b98c | ||
|   | 997d75cc22 | ||
|   | 17ff20d44a | ||
|   | fcbf477bb1 | ||
|   | 4bf89187a9 | ||
|   | c29c4796c7 | ||
|   | 14ea998a12 | ||
|   | 13ed6e84e7 | ||
|   | cfe515c5ac | ||
|   | 1e054cfc7d | 
					 12 changed files with 63 additions and 148 deletions
				
			
		|  | @ -1,7 +1,7 @@ | ||||||
| <Project> | <Project> | ||||||
| 
 | 
 | ||||||
|     <PropertyGroup> |     <PropertyGroup> | ||||||
|         <Version>7.14.12</Version> |         <Version>7.14.10</Version> | ||||||
|     </PropertyGroup> |     </PropertyGroup> | ||||||
| 
 | 
 | ||||||
|     <PropertyGroup> |     <PropertyGroup> | ||||||
|  |  | ||||||
|  | @ -18,8 +18,8 @@ | ||||||
|     <PackageVersion Include="ReactiveUI" Version="20.4.1" /> |     <PackageVersion Include="ReactiveUI" Version="20.4.1" /> | ||||||
|     <PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" /> |     <PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" /> | ||||||
|     <PackageVersion Include="ReactiveUI.WPF" Version="20.4.1" /> |     <PackageVersion Include="ReactiveUI.WPF" Version="20.4.1" /> | ||||||
|     <PackageVersion Include="Semi.Avalonia" Version="11.2.1.10" /> |     <PackageVersion Include="Semi.Avalonia" Version="11.2.1.9" /> | ||||||
|     <PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.10" /> |     <PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.9" /> | ||||||
|     <PackageVersion Include="Splat.NLog" Version="16.2.1" /> |     <PackageVersion Include="Splat.NLog" Version="16.2.1" /> | ||||||
|     <PackageVersion Include="sqlite-net-pcl" Version="1.9.172" /> |     <PackageVersion Include="sqlite-net-pcl" Version="1.9.172" /> | ||||||
|     <PackageVersion Include="TaskScheduler" Version="2.12.2" /> |     <PackageVersion Include="TaskScheduler" Version="2.12.2" /> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| using QRCoder; | using QRCoder; | ||||||
| using QRCoder.Exceptions; |  | ||||||
| using SkiaSharp; | using SkiaSharp; | ||||||
| using ZXing.SkiaSharp; | using ZXing.SkiaSharp; | ||||||
| 
 | 
 | ||||||
|  | @ -9,46 +8,11 @@ public class QRCodeUtils | ||||||
| { | { | ||||||
|     public static byte[]? GenQRCode(string? url) |     public static byte[]? GenQRCode(string? url) | ||||||
|     { |     { | ||||||
|         if (url.IsNullOrEmpty()) |  | ||||||
|         { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         using QRCodeGenerator qrGenerator = new(); |         using QRCodeGenerator qrGenerator = new(); | ||||||
|         DataTooLongException? lastDtle = null; |         using var qrCodeData = qrGenerator.CreateQrCode(url ?? string.Empty, QRCodeGenerator.ECCLevel.Q); | ||||||
| 
 |  | ||||||
|         var levels = new[] |  | ||||||
|         { |  | ||||||
|             QRCodeGenerator.ECCLevel.H, |  | ||||||
|             QRCodeGenerator.ECCLevel.Q, |  | ||||||
|             QRCodeGenerator.ECCLevel.M, |  | ||||||
|             QRCodeGenerator.ECCLevel.L |  | ||||||
|         }; |  | ||||||
|         foreach (var level in levels) |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 using var qrCodeData = qrGenerator.CreateQrCode(url, level); |  | ||||||
|         using PngByteQRCode qrCode = new(qrCodeData); |         using PngByteQRCode qrCode = new(qrCodeData); | ||||||
|         return qrCode.GetGraphic(20); |         return qrCode.GetGraphic(20); | ||||||
|     } |     } | ||||||
|             catch (DataTooLongException ex) |  | ||||||
|             { |  | ||||||
|                 lastDtle = ex; |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             catch |  | ||||||
|             { |  | ||||||
|                 throw; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (lastDtle != null) |  | ||||||
|         { |  | ||||||
|             throw lastDtle; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     public static string? ParseBarcode(string? fileName) |     public static string? ParseBarcode(string? fileName) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -599,7 +599,6 @@ public class Global | ||||||
|             { "cloudflare-dns.com", new List<string> { "104.16.249.249", "104.16.248.249", "2606:4700::6810:f8f9", "2606:4700::6810:f9f9" } }, |             { "cloudflare-dns.com", new List<string> { "104.16.249.249", "104.16.248.249", "2606:4700::6810:f8f9", "2606:4700::6810:f9f9" } }, | ||||||
|             { "dns.cloudflare.com", new List<string> { "104.16.132.229", "104.16.133.229", "2606:4700::6810:84e5", "2606:4700::6810:85e5" } }, |             { "dns.cloudflare.com", new List<string> { "104.16.132.229", "104.16.133.229", "2606:4700::6810:84e5", "2606:4700::6810:85e5" } }, | ||||||
|             { "dot.pub", new List<string> { "1.12.12.12", "120.53.53.53" } }, |             { "dot.pub", new List<string> { "1.12.12.12", "120.53.53.53" } }, | ||||||
|             { "doh.pub", new List<string> { "1.12.12.12", "120.53.53.53" } }, |  | ||||||
|             { "dns.quad9.net", new List<string> { "9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9" } }, |             { "dns.quad9.net", new List<string> { "9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9" } }, | ||||||
|             { "dns.yandex.net", new List<string> { "77.88.8.8", "77.88.8.1", "2a02:6b8::feed:0ff", "2a02:6b8:0:1::feed:0ff" } }, |             { "dns.yandex.net", new List<string> { "77.88.8.8", "77.88.8.1", "2a02:6b8::feed:0ff", "2a02:6b8:0:1::feed:0ff" } }, | ||||||
|             { "dns.sb", new List<string> { "185.222.222.222", "2a09::" } }, |             { "dns.sb", new List<string> { "185.222.222.222", "2a09::" } }, | ||||||
|  |  | ||||||
|  | @ -1258,11 +1258,11 @@ public static class ConfigHandler | ||||||
|                 CoreType = ECoreType.sing_box, |                 CoreType = ECoreType.sing_box, | ||||||
|                 ConfigType = EConfigType.SOCKS, |                 ConfigType = EConfigType.SOCKS, | ||||||
|                 Address = Global.Loopback, |                 Address = Global.Loopback, | ||||||
|                 SpiderX = node.Address, // Tun2SocksAddress |                 Sni = node.Address, //Tun2SocksAddress | ||||||
|                 Port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks) |                 Port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks) | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|         else if (node.ConfigType == EConfigType.Custom && node.ConfigType < EConfigType.Group && node.PreSocksPort > 0) |         else if ((node.ConfigType == EConfigType.Custom && node.ConfigType < EConfigType.Group && node.PreSocksPort > 0)) | ||||||
|         { |         { | ||||||
|             var preCoreType = config.RunningCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray; |             var preCoreType = config.RunningCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray; | ||||||
|             itemSocks = new ProfileItem() |             itemSocks = new ProfileItem() | ||||||
|  |  | ||||||
|  | @ -43,7 +43,16 @@ public partial class CoreConfigSingboxService | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             await GenOutboundDnsRule(node, singboxConfig, Global.SingboxOutboundResolverTag); |             // Tun2SocksAddress | ||||||
|  |             if (node != null && Utils.IsDomain(node.Address)) | ||||||
|  |             { | ||||||
|  |                 singboxConfig.dns.rules ??= new List<Rule4Sbox>(); | ||||||
|  |                 singboxConfig.dns.rules.Insert(0, new Rule4Sbox | ||||||
|  |                 { | ||||||
|  |                     server = Global.SingboxOutboundResolverTag, | ||||||
|  |                     domain = [node.Address], | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         catch (Exception ex) |         catch (Exception ex) | ||||||
|         { |         { | ||||||
|  | @ -337,7 +346,16 @@ public partial class CoreConfigSingboxService | ||||||
|                 await GenDnsDomainsLegacyCompatible(singboxConfig, item); |                 await GenDnsDomainsLegacyCompatible(singboxConfig, item); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             await GenOutboundDnsRule(node, singboxConfig, Global.SingboxFinalResolverTag); |             // Tun2SocksAddress | ||||||
|  |             if (node != null && Utils.IsDomain(node.Address)) | ||||||
|  |             { | ||||||
|  |                 singboxConfig.dns.rules ??= new List<Rule4Sbox>(); | ||||||
|  |                 singboxConfig.dns.rules.Insert(0, new Rule4Sbox | ||||||
|  |                 { | ||||||
|  |                     server = Global.SingboxFinalResolverTag, | ||||||
|  |                     domain = [node.Address], | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         catch (Exception ex) |         catch (Exception ex) | ||||||
|         { |         { | ||||||
|  | @ -407,37 +425,6 @@ public partial class CoreConfigSingboxService | ||||||
|         return await Task.FromResult(0); |         return await Task.FromResult(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private async Task<int> GenOutboundDnsRule(ProfileItem? node, SingboxConfig singboxConfig, string? server) |  | ||||||
|     { |  | ||||||
|         if (node == null) |  | ||||||
|         { |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         var domain = string.Empty; |  | ||||||
|         if (Utils.IsDomain(node.Address)) // normal outbound |  | ||||||
|         { |  | ||||||
|             domain = node.Address; |  | ||||||
|         } |  | ||||||
|         else if (node.Address == Global.Loopback && node.SpiderX.IsNotEmpty() && Utils.IsDomain(node.SpiderX)) // Tun2SocksAddress |  | ||||||
|         { |  | ||||||
|             domain = node.SpiderX; |  | ||||||
|         } |  | ||||||
|         if (domain.IsNullOrEmpty()) |  | ||||||
|         { |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         singboxConfig.dns.rules ??= new List<Rule4Sbox>(); |  | ||||||
|         singboxConfig.dns.rules.Insert(0, new Rule4Sbox |  | ||||||
|         { |  | ||||||
|             server = server, |  | ||||||
|             domain = [domain], |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         return await Task.FromResult(0); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static Server4Sbox? ParseDnsAddress(string address) |     private static Server4Sbox? ParseDnsAddress(string address) | ||||||
|     { |     { | ||||||
|         var addressFirst = address?.Split(address.Contains(',') ? ',' : ';').FirstOrDefault()?.Trim(); |         var addressFirst = address?.Split(address.Contains(',') ? ',' : ';').FirstOrDefault()?.Trim(); | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ public class CheckUpdateViewModel : MyReactiveObject | ||||||
|         this.WhenAnyValue( |         this.WhenAnyValue( | ||||||
|         x => x.EnableCheckPreReleaseUpdate, |         x => x.EnableCheckPreReleaseUpdate, | ||||||
|         y => y == true) |         y => y == true) | ||||||
|             .Subscribe(c => _config.CheckUpdateItem.CheckPreReleaseUpdate = EnableCheckPreReleaseUpdate); |             .Subscribe(c => { _config.CheckUpdateItem.CheckPreReleaseUpdate = EnableCheckPreReleaseUpdate; }); | ||||||
| 
 | 
 | ||||||
|         RefreshCheckUpdateItems(); |         RefreshCheckUpdateItems(); | ||||||
|     } |     } | ||||||
|  | @ -158,8 +158,11 @@ public class CheckUpdateViewModel : MyReactiveObject | ||||||
|                 UpdatedPlusPlus(_geo, ""); |                 UpdatedPlusPlus(_geo, ""); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         await new UpdateService().UpdateGeoFileAll(_config, _updateUI) |         await (new UpdateService()).UpdateGeoFileAll(_config, _updateUI) | ||||||
|             .ContinueWith(t => UpdatedPlusPlus(_geo, "")); |             .ContinueWith(t => | ||||||
|  |             { | ||||||
|  |                 UpdatedPlusPlus(_geo, ""); | ||||||
|  |             }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private async Task CheckUpdateN(bool preRelease) |     private async Task CheckUpdateN(bool preRelease) | ||||||
|  | @ -173,8 +176,11 @@ public class CheckUpdateViewModel : MyReactiveObject | ||||||
|                 UpdatedPlusPlus(_v2rayN, msg); |                 UpdatedPlusPlus(_v2rayN, msg); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         await new UpdateService().CheckUpdateGuiN(_config, _updateUI, preRelease) |         await (new UpdateService()).CheckUpdateGuiN(_config, _updateUI, preRelease) | ||||||
|             .ContinueWith(t => UpdatedPlusPlus(_v2rayN, "")); |             .ContinueWith(t => | ||||||
|  |             { | ||||||
|  |                 UpdatedPlusPlus(_v2rayN, ""); | ||||||
|  |             }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private async Task CheckUpdateCore(CheckUpdateModel model, bool preRelease) |     private async Task CheckUpdateCore(CheckUpdateModel model, bool preRelease) | ||||||
|  | @ -190,8 +196,11 @@ public class CheckUpdateViewModel : MyReactiveObject | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         var type = (ECoreType)Enum.Parse(typeof(ECoreType), model.CoreType); |         var type = (ECoreType)Enum.Parse(typeof(ECoreType), model.CoreType); | ||||||
|         await new UpdateService().CheckUpdateCore(type, _config, _updateUI, preRelease) |         await (new UpdateService()).CheckUpdateCore(type, _config, _updateUI, preRelease) | ||||||
|             .ContinueWith(t => UpdatedPlusPlus(model.CoreType, "")); |             .ContinueWith(t => | ||||||
|  |             { | ||||||
|  |                 UpdatedPlusPlus(model.CoreType, ""); | ||||||
|  |             }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private async Task UpdateFinished() |     private async Task UpdateFinished() | ||||||
|  | @ -302,7 +311,7 @@ public class CheckUpdateViewModel : MyReactiveObject | ||||||
| 
 | 
 | ||||||
|             if (Utils.IsNonWindows()) |             if (Utils.IsNonWindows()) | ||||||
|             { |             { | ||||||
|                 var filesList = new DirectoryInfo(toPath).GetFiles().Select(u => u.FullName).ToList(); |                 var filesList = (new DirectoryInfo(toPath)).GetFiles().Select(u => u.FullName).ToList(); | ||||||
|                 foreach (var file in filesList) |                 foreach (var file in filesList) | ||||||
|                 { |                 { | ||||||
|                     await Utils.SetLinuxChmod(Path.Combine(toPath, item.CoreType.ToLower())); |                     await Utils.SetLinuxChmod(Path.Combine(toPath, item.CoreType.ToLower())); | ||||||
|  |  | ||||||
|  | @ -4,25 +4,19 @@ | ||||||
|     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||||
|     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||||||
|     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||||||
|     xmlns:sys="clr-namespace:System;assembly=netstandard" |     d:DesignHeight="480" | ||||||
|     d:DesignHeight="600" |     d:DesignWidth="400" | ||||||
|     d:DesignWidth="600" |  | ||||||
|     mc:Ignorable="d"> |     mc:Ignorable="d"> | ||||||
| 
 |  | ||||||
|     <UserControl.Resources> |  | ||||||
|         <sys:Double x:Key="QrcodeWidth">500</sys:Double> |  | ||||||
|     </UserControl.Resources> |  | ||||||
| 
 |  | ||||||
|     <Grid Margin="32" RowDefinitions="Auto,Auto"> |     <Grid Margin="32" RowDefinitions="Auto,Auto"> | ||||||
|         <Image |         <Image | ||||||
|             Name="imgQrcode" |             Name="imgQrcode" | ||||||
|             Width="{StaticResource QrcodeWidth}" |             Width="300" | ||||||
|             Height="{StaticResource QrcodeWidth}" /> |             Height="300" /> | ||||||
| 
 | 
 | ||||||
|         <TextBox |         <TextBox | ||||||
|             x:Name="txtContent" |             x:Name="txtContent" | ||||||
|             Grid.Row="1" |             Grid.Row="1" | ||||||
|             Width="{StaticResource QrcodeWidth}" |             Width="300" | ||||||
|             MaxHeight="100" |             MaxHeight="100" | ||||||
|             Margin="{StaticResource MarginTb8}" |             Margin="{StaticResource MarginTb8}" | ||||||
|             VerticalAlignment="Center" |             VerticalAlignment="Center" | ||||||
|  |  | ||||||
|  | @ -22,18 +22,10 @@ public partial class QrcodeView : UserControl | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private Bitmap? GetQRCode(string? url) |     private Bitmap? GetQRCode(string? url) | ||||||
|     { |  | ||||||
|         try |  | ||||||
|     { |     { | ||||||
|         var bytes = QRCodeUtils.GenQRCode(url); |         var bytes = QRCodeUtils.GenQRCode(url); | ||||||
|         return ByteToBitmap(bytes); |         return ByteToBitmap(bytes); | ||||||
|     } |     } | ||||||
|         catch (Exception ex) |  | ||||||
|         { |  | ||||||
|             Logging.SaveLog("GetQRCode", ex); |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     private Bitmap? ByteToBitmap(byte[]? bytes) |     private Bitmap? ByteToBitmap(byte[]? bytes) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -1,24 +0,0 @@ | ||||||
| <Solution> |  | ||||||
|   <Folder Name="/GitHub Action/"> |  | ||||||
|     <File Path="../.github/workflows/build-all.yml" /> |  | ||||||
|     <File Path="../.github/workflows/build-linux.yml" /> |  | ||||||
|     <File Path="../.github/workflows/build-osx.yml" /> |  | ||||||
|     <File Path="../.github/workflows/build-windows-desktop.yml" /> |  | ||||||
|     <File Path="../.github/workflows/build-windows.yml" /> |  | ||||||
|     <File Path="../.github/workflows/winget-publish.yml" /> |  | ||||||
|     <File Path="../package-appimage.sh" /> |  | ||||||
|     <File Path="../package-debian.sh" /> |  | ||||||
|     <File Path="../package-osx.sh" /> |  | ||||||
|     <File Path="../package-release-zip.sh" /> |  | ||||||
|     <File Path="../pkg2appimage.yml" /> |  | ||||||
|   </Folder> |  | ||||||
|   <Folder Name="/Solution Files/"> |  | ||||||
|     <File Path="Directory.Build.props" /> |  | ||||||
|     <File Path="Directory.Packages.props" /> |  | ||||||
|   </Folder> |  | ||||||
|   <Project Path="AmazTool/AmazTool.csproj" /> |  | ||||||
|   <Project Path="GlobalHotKeys/src/GlobalHotKeys/GlobalHotKeys.csproj" /> |  | ||||||
|   <Project Path="ServiceLib/ServiceLib.csproj" /> |  | ||||||
|   <Project Path="v2rayN.Desktop/v2rayN.Desktop.csproj" /> |  | ||||||
|   <Project Path="v2rayN/v2rayN.csproj" /> |  | ||||||
| </Solution> |  | ||||||
|  | @ -20,9 +20,8 @@ public class QRCodeUtils | ||||||
|             var qrCodeImage = ServiceLib.Common.QRCodeUtils.GenQRCode(strContent); |             var qrCodeImage = ServiceLib.Common.QRCodeUtils.GenQRCode(strContent); | ||||||
|             return qrCodeImage is null ? null : ByteToImage(qrCodeImage); |             return qrCodeImage is null ? null : ByteToImage(qrCodeImage); | ||||||
|         } |         } | ||||||
|         catch (Exception ex) |         catch | ||||||
|         { |         { | ||||||
|             Logging.SaveLog("GetQRCode", ex); |  | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -33,8 +32,8 @@ public class QRCodeUtils | ||||||
|         { |         { | ||||||
|             GetDpi(window, out var dpiX, out var dpiY); |             GetDpi(window, out var dpiX, out var dpiY); | ||||||
| 
 | 
 | ||||||
|             var left = (int)SystemParameters.WorkArea.Left; |             var left = (int)(SystemParameters.WorkArea.Left); | ||||||
|             var top = (int)SystemParameters.WorkArea.Top; |             var top = (int)(SystemParameters.WorkArea.Top); | ||||||
|             var width = (int)(SystemParameters.WorkArea.Width / dpiX); |             var width = (int)(SystemParameters.WorkArea.Width / dpiX); | ||||||
|             var height = (int)(SystemParameters.WorkArea.Height / dpiY); |             var height = (int)(SystemParameters.WorkArea.Height / dpiY); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| <UserControl | <UserControl | ||||||
|     x:Class="v2rayN.Views.QrcodeView" |     x:Class="v2rayN.Views.QrcodeView" | ||||||
|     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:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||||
|  | @ -6,33 +6,28 @@ | ||||||
|     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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||||||
|     xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" |     xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" | ||||||
|     xmlns:sys="clr-namespace:System;assembly=mscorlib" |     d:DesignHeight="300" | ||||||
|     d:DesignHeight="600" |     d:DesignWidth="300" | ||||||
|     d:DesignWidth="600" |  | ||||||
|     Style="{StaticResource ViewGlobal}" |     Style="{StaticResource ViewGlobal}" | ||||||
|     mc:Ignorable="d"> |     mc:Ignorable="d"> | ||||||
|     <UserControl.Resources> |  | ||||||
|         <sys:Double x:Key="QrcodeWidth">500</sys:Double> |  | ||||||
|     </UserControl.Resources> |  | ||||||
| 
 |  | ||||||
|     <Grid Margin="32"> |     <Grid Margin="32"> | ||||||
|         <Grid.RowDefinitions> |         <Grid.RowDefinitions> | ||||||
|             <RowDefinition Height="Auto" /> |             <RowDefinition Height="Auto" /> | ||||||
|             <RowDefinition Height="Auto" /> |             <RowDefinition Height="Auto" /> | ||||||
|             <RowDefinition Height="80" /> |             <RowDefinition Height="60" /> | ||||||
|         </Grid.RowDefinitions> |         </Grid.RowDefinitions> | ||||||
| 
 | 
 | ||||||
|         <Image |         <Image | ||||||
|             x:Name="imgQrcode" |             x:Name="imgQrcode" | ||||||
|             Grid.Row="0" |             Grid.Row="0" | ||||||
|             Width="{StaticResource QrcodeWidth}" |             Width="300" | ||||||
|             Height="{StaticResource QrcodeWidth}" |             Height="300" | ||||||
|             Stretch="UniformToFill" /> |             Stretch="UniformToFill" /> | ||||||
| 
 | 
 | ||||||
|         <TextBox |         <TextBox | ||||||
|             x:Name="txtContent" |             x:Name="txtContent" | ||||||
|             Grid.Row="1" |             Grid.Row="1" | ||||||
|             Width="{StaticResource QrcodeWidth}" |             Width="300" | ||||||
|             Margin="0,8" |             Margin="0,8" | ||||||
|             VerticalAlignment="Center" |             VerticalAlignment="Center" | ||||||
|             IsReadOnly="True" |             IsReadOnly="True" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue