分离tab为用户控件

This commit is contained in:
陈国伟 2021-11-04 08:57:58 +08:00
parent 4db6ab6b3f
commit 2a74f7d25d
9 changed files with 147 additions and 106 deletions

View File

@ -89,7 +89,7 @@ namespace FastGithub.UI
var startInfo = new ProcessStartInfo var startInfo = new ProcessStartInfo
{ {
FileName = fileName, FileName = fileName,
Arguments = $"ParentProcessId={Process.GetCurrentProcess().Id} UdpLoggerPort={UdpLoggerPort.Value}", Arguments = $"ParentProcessId={Process.GetCurrentProcess().Id} UdpLoggerPort={UdpLogger.Port}",
UseShellExecute = false, UseShellExecute = false,
CreateNoWindow = true CreateNoWindow = true
}; };

View File

@ -0,0 +1,12 @@
<UserControl x:Class="FastGithub.UI.IssuesWebbrowser"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FastGithub.UI"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<WebBrowser Name="webBrowser" />
</Grid>
</UserControl>

View File

@ -0,0 +1,41 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace FastGithub.UI
{
/// <summary>
/// IssuesWebbrowser.xaml 的交互逻辑
/// </summary>
public partial class IssuesWebbrowser : UserControl
{
public IssuesWebbrowser()
{
InitializeComponent();
this.NavigateIssueHtml();
this.webBrowser.AddHandler(KeyDownEvent, new RoutedEventHandler(WebBrowser_KeyDown), true);
}
/// <summary>
/// 拦截F5
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WebBrowser_KeyDown(object sender, RoutedEventArgs e)
{
var @event = (KeyEventArgs)e;
if (@event.Key == Key.F5)
{
this.NavigateIssueHtml();
}
}
private void NavigateIssueHtml()
{
var resource = Application.GetResourceStream(new Uri("Resource/issue.html", UriKind.Relative));
this.webBrowser.NavigateToStream(resource.Stream);
}
}
}

View File

@ -158,7 +158,7 @@
<TabItem Style="{StaticResource TabItemExWithUnderLineStyle}" Header="问题解答" Height="40" Width="100" Margin="5 0" FontSize="18"> <TabItem Style="{StaticResource TabItemExWithUnderLineStyle}" Header="问题解答" Height="40" Width="100" Margin="5 0" FontSize="18">
<Grid Background="#f7f7f7"> <Grid Background="#f7f7f7">
<WebBrowser Name="webBrowserIssue" /> <local:IssuesWebbrowser/>
</Grid> </Grid>
</TabItem> </TabItem>

View File

@ -2,7 +2,6 @@
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
namespace FastGithub.UI namespace FastGithub.UI
@ -49,27 +48,9 @@ namespace FastGithub.UI
{ {
var version = FileVersionInfo.GetVersionInfo(fileName); var version = FileVersionInfo.GetVersionInfo(fileName);
this.Title = $"{FAST_GITHUB} v{version.ProductVersion}"; this.Title = $"{FAST_GITHUB} v{version.ProductVersion}";
} }
}
this.webBrowserIssue.AddHandler(KeyDownEvent, new RoutedEventHandler(WebBrowser_KeyDown), true);
var resource = Application.GetResourceStream(new Uri("Resource/issue.html", UriKind.Relative));
this.webBrowserIssue.NavigateToStream(resource.Stream);
}
/// <summary>
/// 拦截F5
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WebBrowser_KeyDown(object sender, RoutedEventArgs e)
{
var @event = (KeyEventArgs)e;
if (@event.Key == Key.F5)
{
var resource = Application.GetResourceStream(new Uri("Resource/issue.html", UriKind.Relative));
this.webBrowserIssue.NavigateToStream(resource.Stream);
}
}
/// <summary> /// <summary>
/// 拦截最小化事件 /// 拦截最小化事件

View File

@ -1,4 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Windows; using System.Windows;
namespace FastGithub.UI namespace FastGithub.UI
@ -15,10 +19,14 @@ namespace FastGithub.UI
public string Color => this.Level <= LogLevel.Information ? "#333" : "IndianRed"; public string Color => this.Level <= LogLevel.Information ? "#333" : "IndianRed";
/// <summary>
/// 复制到剪贴板
/// </summary>
public void SetToClipboard() public void SetToClipboard()
{ {
Clipboard.SetText($"{this.Timestamp:yyyy-MM-dd HH:mm:ss.fff}\r\n{this.Message}"); Clipboard.SetText($"{this.Timestamp:yyyy-MM-dd HH:mm:ss.fff}\r\n{this.Message}");
} }
} }
} }

View File

@ -1,10 +1,4 @@
using Newtonsoft.Json; using System.Collections.ObjectModel;
using System;
using System.Collections.ObjectModel;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls; using System.Windows.Controls;
namespace FastGithub.UI namespace FastGithub.UI
@ -14,9 +8,6 @@ namespace FastGithub.UI
/// </summary> /// </summary>
public partial class UdpLogListBox : UserControl public partial class UdpLogListBox : UserControl
{ {
private readonly byte[] buffer = new byte[ushort.MaxValue];
private readonly Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
public ObservableCollection<UdpLog> LogList { get; } = new ObservableCollection<UdpLog>(); public ObservableCollection<UdpLog> LogList { get; } = new ObservableCollection<UdpLog>();
public UdpLogListBox() public UdpLogListBox()
@ -28,36 +19,16 @@ namespace FastGithub.UI
} }
private async void InitUdpLoggerAsync() private async void InitUdpLoggerAsync()
{ {
this.socket.Bind(new IPEndPoint(IPAddress.Loopback, UdpLoggerPort.Value));
while (this.Dispatcher.HasShutdownStarted == false) while (this.Dispatcher.HasShutdownStarted == false)
{ {
var log = await this.GetUdpLogAsync(); var log = await UdpLogger.GetUdpLogAsync();
if (log != null) if (log != null)
{ {
this.LogList.Add(log); this.LogList.Add(log);
} }
} }
} }
private async Task<UdpLog?> GetUdpLogAsync()
{
EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
var taskCompletionSource = new TaskCompletionSource<int>();
this.socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP, this.EndReceiveFrom, taskCompletionSource);
var length = await taskCompletionSource.Task;
var json = Encoding.UTF8.GetString(buffer, 0, length);
return JsonConvert.DeserializeObject<UdpLog>(json);
}
private void EndReceiveFrom(IAsyncResult ar)
{
EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
var length = this.socket.EndReceiveFrom(ar, ref remoteEP);
var taskCompletionSource = (TaskCompletionSource<int>)ar.AsyncState;
taskCompletionSource.TrySetResult(length);
}
private void MenuItem_Copy_Click(object sender, System.Windows.RoutedEventArgs e) private void MenuItem_Copy_Click(object sender, System.Windows.RoutedEventArgs e)
{ {

View File

@ -0,0 +1,77 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace FastGithub.UI
{
static class UdpLogger
{
private static readonly byte[] buffer = new byte[ushort.MaxValue];
private static readonly Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
/// <summary>
/// 获取日志端口
/// </summary>
public static int Port { get; } = GetAvailableUdpPort(38457);
static UdpLogger()
{
socket.Bind(new IPEndPoint(IPAddress.Loopback, Port));
}
/// <summary>
/// 获取可用的随机Udp端口
/// </summary>
/// <param name="minValue"></param>
/// <param name="addressFamily"></param>
/// <returns></returns>
private static int GetAvailableUdpPort(int minValue, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
var hashSet = new HashSet<int>();
var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners();
foreach (var endpoint in tcpListeners)
{
if (endpoint.AddressFamily == addressFamily)
{
hashSet.Add(endpoint.Port);
}
}
for (var port = minValue; port < IPEndPoint.MaxPort; port++)
{
if (hashSet.Contains(port) == false)
{
return port;
}
}
throw new ArgumentException("当前无可用的端口");
}
public static async Task<UdpLog?> GetUdpLogAsync()
{
EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
var taskCompletionSource = new TaskCompletionSource<int>();
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP, EndReceiveFrom, taskCompletionSource);
var length = await taskCompletionSource.Task;
var json = Encoding.UTF8.GetString(buffer, 0, length);
return JsonConvert.DeserializeObject<UdpLog>(json);
}
private static void EndReceiveFrom(IAsyncResult ar)
{
EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
var length = socket.EndReceiveFrom(ar, ref remoteEP);
var taskCompletionSource = (TaskCompletionSource<int>)ar.AsyncState;
taskCompletionSource.TrySetResult(length);
}
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace FastGithub.UI
{
/// <summary>
/// udp日志工具类
/// </summary>
static class UdpLoggerPort
{
/// <summary>
/// 获取日志端口
/// </summary>
public static int Value { get; } = GetAvailableUdpPort(38457);
/// <summary>
/// 获取可用的随机Udp端口
/// </summary>
/// <param name="minValue"></param>
/// <param name="addressFamily"></param>
/// <returns></returns>
private static int GetAvailableUdpPort(int minValue, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
var hashSet = new HashSet<int>();
var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners();
foreach (var endpoint in tcpListeners)
{
if (endpoint.AddressFamily == addressFamily)
{
hashSet.Add(endpoint.Port);
}
}
for (var port = minValue; port < IPEndPoint.MaxPort; port++)
{
if (hashSet.Contains(port) == false)
{
return port;
}
}
throw new ArgumentException("当前无可用的端口");
}
}
}