diff --git a/YandereLinks/App.xaml.cs b/YandereLinks/App.xaml.cs
index 0ec610a..f872934 100644
--- a/YandereLinks/App.xaml.cs
+++ b/YandereLinks/App.xaml.cs
@@ -4,7 +4,7 @@
namespace XstarS.YandereLinks
{
///
- /// App.xaml 的交互逻辑。
+ /// 表示应用程序的入口点。
///
public partial class App : Application
{
diff --git a/YandereLinks/Commands/CommandBase.cs b/YandereLinks/Commands/CommandBase.cs
deleted file mode 100644
index 978277d..0000000
--- a/YandereLinks/Commands/CommandBase.cs
+++ /dev/null
@@ -1,191 +0,0 @@
-using System;
-using System.Threading;
-using System.Windows.Input;
-
-namespace XstarS.ComponentModel
-{
- ///
- /// 提供命令 的无参数的抽象基类。
- ///
- public abstract class CommandBase : ICommand
- {
- ///
- /// 的值。
- ///
- private bool _IsExecutable = true;
-
- ///
- /// 创建当前命令的线程的同步上下文。
- ///
- private readonly SynchronizationContext InitSyncContext;
-
- ///
- /// 初始化 类的新实例。
- ///
- protected CommandBase()
- {
- this.InitSyncContext = SynchronizationContext.Current;
- }
-
- ///
- /// 获取或设置此命令是否可在其当前状态下执行。
- ///
- protected bool IsExecutable
- {
- get => this._IsExecutable;
- set { this._IsExecutable = value; this.OnCanExecuteChanged(); }
- }
-
- ///
- /// 当出现影响是否应执行该命令的更改时发生。
- ///
- public event EventHandler CanExecuteChanged;
-
- ///
- /// 在当前状态下执行此命令。
- ///
- public abstract void Execute();
-
- ///
- /// 确定此命令是否可在其当前状态下执行。
- ///
- /// 如果可执行此命令,则为 ;
- /// 否则为 。
- public virtual bool CanExecute() => this.IsExecutable;
-
- ///
- /// 引发 事件。
- ///
- protected virtual void OnCanExecuteChanged()
- {
- if ((this.InitSyncContext is null) ||
- (this.InitSyncContext == SynchronizationContext.Current))
- {
- this.OnCanExecuteChanged(null);
- }
- else
- {
- this.InitSyncContext.Post(this.OnCanExecuteChanged, null);
- }
- }
-
- ///
- /// 引发 事件。
- ///
- /// 不使用此参数。
- private void OnCanExecuteChanged(object unused)
- {
- this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);
- }
-
- ///
- /// 在当前状态下执行此命令。
- ///
- /// 此命令使用的数据。不使用此参数。
- void ICommand.Execute(object parameter) => this.Execute();
-
- ///
- /// 确定此命令是否可在其当前状态下执行。
- ///
- /// 此命令使用的数据。不使用此参数。
- /// 如果可执行此命令,则为 ;
- /// 否则为 。
- bool ICommand.CanExecute(object parameter) => this.CanExecute();
- }
-
- ///
- /// 提供命令 的有参数的抽象基类。
- ///
- /// 命令使用的数据的类型。
- public abstract class CommandBase : ICommand
- {
- ///
- /// 的值。
- ///
- private bool _IsExecutable = true;
-
- ///
- /// 创建当前命令的线程的同步上下文。
- ///
- private readonly SynchronizationContext InitSyncContext;
-
- ///
- /// 初始化 类的新实例。
- ///
- protected CommandBase()
- {
- this.InitSyncContext = SynchronizationContext.Current;
- }
-
- ///
- /// 获取或设置此命令是否可在其当前状态下执行。
- ///
- protected bool IsExecutable
- {
- get => this._IsExecutable;
- set { this._IsExecutable = value; this.OnCanExecuteChanged(); }
- }
-
- ///
- /// 当出现影响是否应执行该命令的更改时发生。
- ///
- public event EventHandler CanExecuteChanged;
-
- ///
- /// 在当前状态下执行此命令。
- ///
- /// 此命令使用的数据。
- public abstract void Execute(TParameter parameter);
-
- ///
- /// 确定此命令是否可在其当前状态下执行。
- ///
- /// 此命令使用的数据。
- /// 如果可执行此命令,则为 ;
- /// 否则为 。
- public virtual bool CanExecute(TParameter parameter) => this.IsExecutable;
-
- ///
- /// 引发 事件。
- ///
- protected virtual void OnCanExecuteChanged()
- {
- if ((this.InitSyncContext is null) ||
- (this.InitSyncContext == SynchronizationContext.Current))
- {
- this.OnCanExecuteChanged(null);
- }
- else
- {
- this.InitSyncContext.Post(this.OnCanExecuteChanged, null);
- }
- }
-
- ///
- /// 引发 事件。
- ///
- /// 不使用此参数。
- private void OnCanExecuteChanged(object unused)
- {
- this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);
- }
-
- ///
- /// 在当前状态下执行此命令。
- ///
- /// 此命令使用的数据。
- ///
- /// 不为 类型。
- void ICommand.Execute(object parameter) => this.Execute((TParameter)parameter);
-
- ///
- /// 确定此命令是否可在其当前状态下执行。
- ///
- /// 此命令使用的数据。
- /// 如果可执行此命令,则为 ;
- /// 否则为 。
- ///
- /// 不为 类型。
- bool ICommand.CanExecute(object parameter) => this.CanExecute((TParameter)parameter);
- }
-}
diff --git a/YandereLinks/Commands/DelegateCommand.cs b/YandereLinks/Commands/DelegateCommand.cs
deleted file mode 100644
index e5f20c5..0000000
--- a/YandereLinks/Commands/DelegateCommand.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-using System;
-using System.Windows.Input;
-
-namespace XstarS.ComponentModel
-{
- ///
- /// 表示由委托 定义的无参数的命令 。
- ///
- public sealed class DelegateCommand : CommandBase
- {
- ///
- /// 方法的委托。
- ///
- private readonly Action ExecuteDelegate;
-
- ///
- /// 方法的委托。
- ///
- private readonly Func CanExecuteDelegate;
-
- ///
- /// 使用指定的委托初始化 类的新实例。
- ///
- ///
- /// 方法的委托。
- ///
- /// 为 。
- public DelegateCommand(Action executeDelegate)
- {
- this.ExecuteDelegate = executeDelegate ??
- throw new ArgumentNullException(nameof(executeDelegate));
- this.CanExecuteDelegate = base.CanExecute;
- }
-
- ///
- /// 使用指定的委托初始化 类的新实例。
- ///
- ///
- /// 方法的委托。
- ///
- /// 方法的委托。
- ///
- /// 或 为 。
- public DelegateCommand(Action executeDelegate, Func canExecuteDelegate)
- {
- this.ExecuteDelegate = executeDelegate ??
- throw new ArgumentNullException(nameof(executeDelegate));
- this.CanExecuteDelegate = canExecuteDelegate ??
- throw new ArgumentNullException(nameof(canExecuteDelegate));
- }
-
- ///
- /// 在当前状态下执行此命令。
- ///
- public override void Execute()
- {
- this.ExecuteDelegate.Invoke();
- }
-
- ///
- /// 确定此命令是否可在其当前状态下执行。
- ///
- /// 如果可执行此命令,则为 ;
- /// 否则为 。
- public override bool CanExecute()
- {
- return this.CanExecuteDelegate.Invoke();
- }
-
- ///
- /// 通知当前命令的可执行状态已更改。
- ///
- public void NotifyCanExecuteChanged() => this.OnCanExecuteChanged();
- }
-
- ///
- /// 表示由委托 定义的有参数的命令 。
- ///
- /// 命令使用的数据的类型。
- public sealed class DelegateCommand : CommandBase
- {
- ///
- /// 方法的委托。
- ///
- private readonly Action ExecuteDelegate;
-
- ///
- /// 方法的委托。
- ///
- private readonly Func CanExecuteDelegate;
-
- ///
- /// 使用指定的委托初始化 类的新实例。
- ///
- ///
- /// 方法的委托。
- ///
- /// 为 。
- public DelegateCommand(Action executeDelegate)
- {
- this.ExecuteDelegate = executeDelegate ??
- throw new ArgumentNullException(nameof(executeDelegate));
- this.CanExecuteDelegate = base.CanExecute;
- }
-
- ///
- /// 使用指定的委托初始化 类的新实例。
- ///
- ///
- /// 方法的委托。
- ///
- /// 方法的委托。
- ///
- /// 或 为 。
- public DelegateCommand(Action executeDelegate,
- Func canExecuteDelegate)
- {
- this.ExecuteDelegate = executeDelegate ??
- throw new ArgumentNullException(nameof(executeDelegate));
- this.CanExecuteDelegate = canExecuteDelegate ??
- throw new ArgumentNullException(nameof(canExecuteDelegate));
- }
-
- ///
- /// 在当前状态下执行此命令。
- ///
- /// 此命令使用的数据。
- public override void Execute(TParameter parameter)
- {
- this.ExecuteDelegate.Invoke(parameter);
- }
-
- ///
- /// 确定此命令是否可在其当前状态下执行。
- ///
- /// 此命令使用的数据。
- /// 如果可执行此命令,则为 ;
- /// 否则为 。
- public override bool CanExecute(TParameter parameter)
- {
- return this.CanExecuteDelegate.Invoke(parameter);
- }
-
- ///
- /// 通知当前命令的可执行状态已更改。
- ///
- public void NotifyCanExecuteChanged() => this.OnCanExecuteChanged();
- }
-}
diff --git a/YandereLinks/Helpers/ConsoleManager.cs b/YandereLinks/Helpers/ConsoleManager.cs
index 20ab624..1285a82 100644
--- a/YandereLinks/Helpers/ConsoleManager.cs
+++ b/YandereLinks/Helpers/ConsoleManager.cs
@@ -59,7 +59,7 @@ public static void Show()
if (!ConsoleManager.HasConsole)
{
ConsoleManager.SafeNativeMethods.AllocConsole();
- ConsoleManager.InvalidateStdOutError();
+ ConsoleManager.InitializeStdOutError();
}
}
@@ -91,9 +91,9 @@ public static void Toggle()
}
///
- /// 释放 的标准输出流和错误流,以触发其重新初始化。
+ /// 重新初始化 的标准输出流和错误流。
///
- private static void InvalidateStdOutError()
+ private static void InitializeStdOutError()
{
var t_Console = typeof(Console);
var staticNoPublic = BindingFlags.Static | BindingFlags.NonPublic;
diff --git a/YandereLinks/Helpers/ControlExtensions.cs b/YandereLinks/Helpers/ControlExtensions.cs
deleted file mode 100644
index 1ded439..0000000
--- a/YandereLinks/Helpers/ControlExtensions.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-using System.Reflection;
-using System.Windows.Controls;
-
-namespace XstarS.Windows.Controls
-{
- ///
- /// 提供 WPF 用户控件 及其派生类的扩展方法。
- ///
- internal static class ControlExtensions
- {
- ///
- /// 设定是否禁止当前 的脚本错误提示。
- ///
- /// 要设定脚本错误提示的 对象。
- /// 指示是否要禁止脚本错误提示。
- ///
- /// 为 。
- public static void SuppressScriptErrors(this WebBrowser browser, bool supresses = true)
- {
- if (browser is null)
- {
- throw new ArgumentNullException(nameof(browser));
- }
-
- var if__axIWebBrowser2 = typeof(WebBrowser).GetField(
- "_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
- if (if__axIWebBrowser2 is null) { return; }
-
- var _axIWebBrowser2 = if__axIWebBrowser2.GetValue(browser);
- if (_axIWebBrowser2 is null) { return; }
-
- _axIWebBrowser2.GetType().InvokeMember(
- "Silent", BindingFlags.SetProperty, null, _axIWebBrowser2, new object[] { supresses });
- }
- }
-}
diff --git a/YandereLinks/Helpers/SystemComponents.cs b/YandereLinks/Helpers/SystemComponents.cs
index f03ceaf..ada33da 100644
--- a/YandereLinks/Helpers/SystemComponents.cs
+++ b/YandereLinks/Helpers/SystemComponents.cs
@@ -28,7 +28,7 @@ public static Version Version
using (var regKeyIE = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\Internet Explorer"))
{
- string versionSz = (regKeyIE.GetValue("svcVersion") ??
+ var versionSz = (regKeyIE.GetValue("svcVersion") ??
regKeyIE.GetValue("Version")) as string;
return (versionSz is null) ? null : new Version(versionSz);
}
@@ -67,7 +67,7 @@ public static class WebBrowser
@"SOFTWARE\Microsoft\Internet Explorer\" +
@"MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", false))
{
- string appName = AppDomain.CurrentDomain.FriendlyName;
+ var appName = AppDomain.CurrentDomain.FriendlyName;
return regKeyBrowser.GetValue(appName) as int?;
}
}
@@ -84,7 +84,7 @@ public static class WebBrowser
@"SOFTWARE\Microsoft\Internet Explorer\" +
@"MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", true))
{
- string appName = AppDomain.CurrentDomain.FriendlyName;
+ var appName = AppDomain.CurrentDomain.FriendlyName;
if (value is null)
{
regKeyBrowser.DeleteValue(appName);
@@ -131,7 +131,7 @@ public static class WebBrowser
@"SOFTWARE\Microsoft\Internet Explorer\" +
@"MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", false))
{
- string appName = AppDomain.CurrentDomain.FriendlyName;
+ var appName = AppDomain.CurrentDomain.FriendlyName;
return regKeyBrowser.GetValue(appName) as int?;
}
}
@@ -148,7 +148,7 @@ public static class WebBrowser
@"SOFTWARE\Microsoft\Internet Explorer\" +
@"MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", true))
{
- string appName = AppDomain.CurrentDomain.FriendlyName;
+ var appName = AppDomain.CurrentDomain.FriendlyName;
if (value is null)
{
regKeyBrowser.DeleteValue(appName);
diff --git a/YandereLinks/Models/YanderePage.cs b/YandereLinks/Models/YanderePage.cs
index c6c346d..8e2575f 100644
--- a/YandereLinks/Models/YanderePage.cs
+++ b/YandereLinks/Models/YanderePage.cs
@@ -61,22 +61,19 @@ public class YanderePage : IDisposable, IReadOnlyList
protected static readonly string NextPageLinkPrefix;
///
- /// 页面的链接。
- /// 使用 访问以执行对象释放检查。
+ /// 指示当前对象是否已经被释放。
///
- private readonly string _PageLink;
+ private volatile bool IsDisposed = false;
///
- /// 用于 HTTP 访问的客户端对象。
- /// 使用 访问以执行对象释放检查。
+ /// 的值。
///
private HttpClient _HttpClient;
///
- /// 获取 HTML 文本的任务。
- /// 使用 访问以执行对象释放检查。
+ /// 的值。
///
- private Task _DocumentTextTask;
+ private Task _DocumentTextAsync;
///
/// 初始化 类的静态成员。
@@ -107,112 +104,94 @@ static YanderePage()
/// 为 。
///
/// 不为合法的绝对 URI。
- public YanderePage(string pageLink) : this(pageLink, true) { }
-
- ///
- /// 使用页面的链接和 HTML 文本初始化 类的新实例。
- ///
- /// 页面的链接。
- /// 页面的 HTML 文本。
- /// 或
- /// 为 。
- ///
- /// 不为合法的绝对 URI。
- public YanderePage(string pageLink, string documentText) : this(pageLink, false)
+ public YanderePage(string pageLink)
{
- if (documentText is null)
+ if (pageLink is null)
{
- throw new ArgumentNullException(nameof(documentText));
+ throw new ArgumentNullException(nameof(pageLink));
+ }
+ if (!Uri.TryCreate(pageLink, UriKind.Absolute, out _))
+ {
+ throw new ArgumentException(new ArgumentException().Message, nameof(pageLink));
}
- this._DocumentTextTask = new Task(() => documentText);
- this._DocumentTextTask.RunSynchronously();
+ this.PageLink = pageLink;
+ this.HttpClient = new HttpClient();
+ this.DocumentTextAsync = this._HttpClient.GetStringAsync(pageLink);
}
///
- /// 使用页面的链接初始化 类的新实例,
- /// 并指定是否获取页面的 HTML 文本。
+ /// 使用页面的链接和 HTML 文本初始化 类的新实例。
///
- ///
- /// 若在派生类的初始化方法中调用了此初始化方法,
- /// 应重写 属性,
- /// 以确保基类能够正确读取页面的 HTML 文本并获取链接。
- ///
/// 页面的链接。
- /// 指示是否获取页面的 HTML 文本。
- ///
- /// 为 。
+ /// 页面的 HTML 文本。
+ /// 或
+ /// 为 。
///
/// 不为合法的绝对 URI。
- protected YanderePage(string pageLink, bool getsDocument)
+ public YanderePage(string pageLink, string documentText)
{
if (pageLink is null)
{
throw new ArgumentNullException(nameof(pageLink));
}
- else if (!Uri.TryCreate(pageLink, UriKind.Absolute, out var _))
+ if (!Uri.TryCreate(pageLink, UriKind.Absolute, out var _))
{
throw new ArgumentException(new ArgumentException().Message, nameof(pageLink));
}
+ if (documentText is null)
+ {
+ throw new ArgumentNullException(nameof(documentText));
+ }
- this._PageLink = pageLink;
- this._HttpClient = new HttpClient();
- this._DocumentTextTask = getsDocument ?
- this._HttpClient.GetStringAsync(pageLink) : null;
+ this.PageLink = pageLink;
+ this.DocumentTextAsync = Task.Run(() => documentText);
}
- ///
- /// 指示当前对象是否已经被释放。
- ///
- protected bool IsDisposed { get; private set; } = false;
-
- ///
- /// 获取当前对象,并检查当前对象是否已经被释放。
- ///
- /// 当前对象已经被释放。
- protected YanderePage Disposable => this.IsDisposed ?
- throw new ObjectDisposedException(this.GetType().ToString()) : this;
-
///
/// 页面的链接。
///
- public string PageLink => this.Disposable._PageLink;
+ public string PageLink { get; }
///
/// 用于 HTTP 访问的客户端对象。
///
private HttpClient HttpClient
{
- get => this.Disposable._HttpClient;
- set => this.Disposable._HttpClient = value;
+ get => !this.IsDisposed ? this._HttpClient :
+ throw new ObjectDisposedException(this.GetType().ToString());
+ set => this._HttpClient = !this.IsDisposed ? value :
+ throw new ObjectDisposedException(this.GetType().ToString());
}
///
- /// 获取 HTML 文本的任务。
+ /// 异步获取页面的 HTML 文本。
///
- private Task DocumentTextTask
+ public Task DocumentTextAsync
{
- get => this.Disposable._DocumentTextTask;
- set => this.Disposable._DocumentTextTask = value;
+ get => !this.IsDisposed ? this._DocumentTextAsync :
+ throw new ObjectDisposedException(this.GetType().ToString());
+ private set => this._DocumentTextAsync = !this.IsDisposed ? value :
+ throw new ObjectDisposedException(this.GetType().ToString());
}
///
- /// 页面的 HTML 文本。
+ /// 获取页面的 HTML 文本。
///
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public virtual string DocumentText
+ public string DocumentText
{
get
{
- if (this.DocumentTextTask is null)
+ if (this.DocumentTextAsync is null)
{
return string.Empty;
}
try
{
- return this.DocumentTextTask.Result;
+ return this.DocumentTextAsync.Result;
}
catch (Exception e)
when (e.InnerException is TaskCanceledException)
@@ -251,22 +230,22 @@ public virtual string DocumentText
}
///
- /// 当前页面的索引。
+ /// 获取当前页面的索引。
///
public int Index
{
get
{
- string pageIndexPrefix = "page=";
- string pageLink = this.PageLink;
+ var pageIndexPrefix = "page=";
+ var pageLink = this.PageLink;
if (!pageLink.Contains(pageIndexPrefix))
{
return 1;
}
- string pageIndexString = string.Empty;
- int startIndex = pageLink.IndexOf(pageIndexPrefix) +
+ var pageIndexString = string.Empty;
+ var startIndex = pageLink.IndexOf(pageIndexPrefix) +
pageIndexPrefix.Length;
for (int i = startIndex; i < pageLink.Length; i++)
{
@@ -284,13 +263,13 @@ public int Index
}
///
- /// 当前页面能够直接导航的页面数量。
+ /// 获取当前页面能够直接导航的页面数量。
///
public int Count
{
get
{
- string documentText = this.DocumentText;
+ var documentText = this.DocumentText;
if (!documentText.Contains(YanderePage.NextPageLinkPrefix))
{
@@ -298,8 +277,8 @@ public int Count
this.Index : 1;
}
- string lastPageIndexString = string.Empty;
- int endIndex = documentText.IndexOf(YanderePage.NextPageLinkPrefix);
+ var lastPageIndexString = string.Empty;
+ var endIndex = documentText.IndexOf(YanderePage.NextPageLinkPrefix);
for (int i = endIndex; i >= 0; i--)
{
if (char.IsDigit(documentText[i]))
@@ -316,20 +295,20 @@ public int Count
}
///
- /// 页面包含的图片链接。
+ /// 获取页面包含的图片链接。
///
public string[] ImageLinks
{
get
{
- string documentText = this.DocumentText;
+ var documentText = this.DocumentText;
var imageLinks = new List();
while (documentText.Contains(YanderePage.ImageLinkPrefix))
{
- int startIndex = documentText.IndexOf(YanderePage.ImageLinkPrefix) +
+ var startIndex = documentText.IndexOf(YanderePage.ImageLinkPrefix) +
YanderePage.ImageLinkPrefix.Length;
- string imageLink = documentText.Substring(startIndex);
+ var imageLink = documentText.Substring(startIndex);
imageLink = imageLink.Remove(imageLink.IndexOf('"'));
imageLinks.Add(imageLink);
documentText = documentText.Substring(startIndex);
@@ -339,20 +318,20 @@ public string[] ImageLinks
}
///
- /// Pools 页面的所有 Pool 页面的链接。
+ /// 获取 Pools 页面的所有 Pool 页面的链接。
///
public string[] PoolPageLinks
{
get
{
- string documentText = this.DocumentText;
+ var documentText = this.DocumentText;
var poolPageLinks = new List();
while (documentText.Contains(YanderePage.PoolPageLinkPrefix))
{
- int startIndex = documentText.IndexOf(YanderePage.PoolPageLinkPrefix) +
+ var startIndex = documentText.IndexOf(YanderePage.PoolPageLinkPrefix) +
YanderePage.PoolPageLinkPrefix.Length;
- string poolPageLink = documentText.Substring(startIndex);
+ var poolPageLink = documentText.Substring(startIndex);
poolPageLink = poolPageLink.Remove(poolPageLink.IndexOf('"'));
poolPageLinks.Add(YanderePage.PoolPageLinkStatic + poolPageLink);
documentText = documentText.Substring(startIndex);
@@ -362,69 +341,69 @@ public string[] PoolPageLinks
}
///
- /// Pools 页面的所有 Pool 页面的 对象。
+ /// 获取 Pools 页面的所有 Pool 页面的 对象。
///
public YanderePage[] PoolPages =>
Array.ConvertAll(this.PoolPageLinks, pageLink => new YanderePage(pageLink));
///
- /// 上一页面的链接。
+ /// 获取上一页面的链接。
///
public string PrevPageLink
{
get
{
- string documentText = this.DocumentText;
+ var documentText = this.DocumentText;
if (!documentText.Contains(YanderePage.PrevPageLinkPrefix))
{
return null;
}
- int startIndex = documentText.IndexOf(YanderePage.PrevPageLinkPrefix) +
+ var startIndex = documentText.IndexOf(YanderePage.PrevPageLinkPrefix) +
YanderePage.PrevPageLinkPrefix.Length;
- string prevPageLink = documentText.Substring(startIndex);
+ var prevPageLink = documentText.Substring(startIndex);
prevPageLink = prevPageLink.Remove(prevPageLink.IndexOf('"'));
return YanderePage.IndexPageLink + prevPageLink;
}
}
///
- /// 上一页面的 对象。
+ /// 获取上一页面的 对象。
///
public YanderePage PrevPage =>
(this.PrevPageLink is null) ? null : new YanderePage(this.PrevPageLink);
///
- /// 下一页面的链接。
+ /// 获取下一页面的链接。
///
public string NextPageLink
{
get
{
- string documentText = this.DocumentText;
+ var documentText = this.DocumentText;
if (!documentText.Contains(YanderePage.NextPageLinkPrefix))
{
return null;
}
- int startIndex = documentText.IndexOf(YanderePage.NextPageLinkPrefix) +
+ var startIndex = documentText.IndexOf(YanderePage.NextPageLinkPrefix) +
YanderePage.NextPageLinkPrefix.Length;
- string nextPageLink = documentText.Substring(startIndex);
+ var nextPageLink = documentText.Substring(startIndex);
nextPageLink = nextPageLink.Remove(nextPageLink.IndexOf('"'));
return YanderePage.IndexPageLink + nextPageLink;
}
}
///
- /// 下一页面的 对象。
+ /// 获取下一页面的 对象。
///
public YanderePage NextPage =>
(this.NextPageLink is null) ? null : new YanderePage(this.NextPageLink);
///
- /// 指示页面是否为 yande.re 的页面。
+ /// 确定指定页面是否为 yande.re 的页面。
///
/// 待验证的 对象。
/// 若 为 yande.re 的页面,
@@ -434,7 +413,7 @@ public string NextPageLink
page.PageLink.StartsWith(YanderePage.IndexPageLink);
///
- /// 指示页面是否为 Posts 页面。
+ /// 确定指定页面是否为 Posts 页面。
///
/// 待验证的 对象。
/// 若 为 Posts 页面,
@@ -445,7 +424,7 @@ public string NextPageLink
!page.PageLink.StartsWith(YanderePage.PostPageLinkStatic);
///
- /// 指示页面是否为 Pools 页面。
+ /// 确定指定页面是否为 Pools 页面。
///
/// 待验证的 对象。
/// 若 为 Pools 页面,
@@ -456,7 +435,7 @@ public string NextPageLink
!page.PageLink.StartsWith(YanderePage.PoolPageLinkStatic);
///
- /// 指示页面是否为 Post 页面。
+ /// 确定指定页面是否为 Post 页面。
///
/// 待验证的 对象。
/// 若 为 Post 页面,
@@ -466,7 +445,7 @@ public string NextPageLink
page.PageLink.StartsWith(YanderePage.PostPageLinkStatic);
///
- /// 指示页面是否为 Pool 页面。
+ /// 确定指定页面是否为 Pool 页面。
///
/// 待验证的 对象。
/// 若 为 Pool 页面,
@@ -490,15 +469,15 @@ public YanderePage PageAt(int index)
return this;
}
- string pageIndexPrefix = "page=";
- string pageLink = (this.PageLink == YanderePage.IndexPageLink) ?
+ var pageIndexPrefix = "page=";
+ var pageLink = (this.PageLink == YanderePage.IndexPageLink) ?
YanderePage.PostsPageLink : this.PageLink;
string indexPageLink;
if (pageLink.Contains(pageIndexPrefix))
{
- int pageIndexLength = 0;
- int startIndex = pageLink.IndexOf(pageIndexPrefix) + pageIndexPrefix.Length;
+ var pageIndexLength = 0;
+ var startIndex = pageLink.IndexOf(pageIndexPrefix) + pageIndexPrefix.Length;
for (int i = startIndex; i < pageLink.Length; i++)
{
if (char.IsDigit(pageLink[i]))
@@ -510,12 +489,12 @@ public YanderePage PageAt(int index)
break;
}
}
- indexPageLink = pageLink.Remove(startIndex, pageIndexLength).
- Insert(startIndex, index.ToString());
+ indexPageLink = pageLink.Remove(
+ startIndex, pageIndexLength).Insert(startIndex, index.ToString());
}
else
{
- string paramModifier = pageLink.Contains("?") ? "&" : "?";
+ var paramModifier = pageLink.Contains("?") ? "&" : "?";
indexPageLink = pageLink + paramModifier + pageIndexPrefix + index.ToString();
}
return new YanderePage(indexPageLink);
@@ -527,8 +506,8 @@ public YanderePage PageAt(int index)
public virtual void Refresh()
{
this.Cancel();
- this.DocumentTextTask?.Dispose();
- this.DocumentTextTask = this.HttpClient?.GetStringAsync(this.PageLink);
+ this.DocumentTextAsync?.Dispose();
+ this.DocumentTextAsync = this.HttpClient?.GetStringAsync(this.PageLink);
}
///
@@ -539,7 +518,7 @@ public virtual void Refresh()
public virtual void Cancel()
{
this.HttpClient?.CancelPendingRequests();
- try { this.DocumentTextTask?.Wait(); } catch { }
+ try { this.DocumentTextAsync?.Wait(); } catch { }
}
///
@@ -568,10 +547,10 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
this.Cancel();
- this._DocumentTextTask?.Dispose();
- this._DocumentTextTask = null;
- this._HttpClient?.Dispose();
- this._HttpClient = null;
+ this.DocumentTextAsync?.Dispose();
+ this.DocumentTextAsync = null;
+ this.HttpClient?.Dispose();
+ this.HttpClient = null;
}
this.IsDisposed = true;
diff --git a/YandereLinks/Properties/AssemblyInfo.cs b/YandereLinks/Properties/AssemblyInfo.cs
index 79f0eef..d688267 100644
--- a/YandereLinks/Properties/AssemblyInfo.cs
+++ b/YandereLinks/Properties/AssemblyInfo.cs
@@ -49,5 +49,5 @@
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.3.0.0")]
-[assembly: AssemblyFileVersion("1.3.0.0")]
+[assembly: AssemblyVersion("1.3.1.0")]
+[assembly: AssemblyFileVersion("1.3.1.0")]
diff --git a/YandereLinks/ViewModels/MainWindowModel.cs b/YandereLinks/ViewModels/MainWindowModel.cs
index 7057030..8d7b8bc 100644
--- a/YandereLinks/ViewModels/MainWindowModel.cs
+++ b/YandereLinks/ViewModels/MainWindowModel.cs
@@ -2,7 +2,6 @@
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
using XstarS.ComponentModel;
using XstarS.YandereLinks.Models;
@@ -18,16 +17,10 @@ public class MainWindowModel : ObservableStorage
///
public MainWindowModel()
{
- this.ExtractCancellationSource = new CancellationTokenSource();
- this.ExtractLinksCommand = this.CreateExtractLinksCommand();
- this.EnumerateExtractLinksCommand = this.CreateEnumerateExtractLinksCommand();
- this.CancelExtractLinksCommand = this.CreateCancelExtractLinksCommand();
- this.CopyLinksCommand = this.CreateCopyLinksCommand();
- this.ClearLinksCommand = this.CreateClearLinksCommand();
-
this.PageLink = this.HomePageLink;
this.ImageLinks = string.Empty;
this.CanExtract = true;
+ this.ExtractCancellationSource = new CancellationTokenSource();
}
///
@@ -106,129 +99,58 @@ private void ExtractImageLinks()
}
///
- /// 表示提取图片链接的命令。
- ///
- public DelegateCommand ExtractLinksCommand { get; }
-
- ///
- /// 创建 。
+ /// 异步提取当前页面包含的图片链接。
///
- /// 。
- private DelegateCommand CreateExtractLinksCommand()
+ public Task ExtractImageLinksAsync()
{
- return new DelegateCommand(
- () => Task.Run(() =>
+ return Task.Run(() =>
+ {
+ if (this.CanExtract)
{
- if (this.CanExtract)
- {
- this.CanExtract = false;
- this.ExtractImageLinks();
- this.CanExtract = true;
- }
- }),
- () => this.CanExtract);
+ this.CanExtract = false;
+ this.ExtractImageLinks();
+ this.CanExtract = true;
+ }
+ });
}
///
- /// 表示遍历页面并提取图片链接的命令。
- ///
- public DelegateCommand EnumerateExtractLinksCommand { get; }
-
- ///
- /// 创建 。
+ /// 异步提取当前页面到最后页面包含的图片链接。
///
- /// 。
- private DelegateCommand CreateEnumerateExtractLinksCommand()
+ public Task EnumeratePageExtractAsync()
{
- return new DelegateCommand(
- () => Task.Run(() =>
+ return Task.Run(() =>
+ {
+ if (this.CanExtract)
{
- if (this.CanExtract)
+ this.CanExtract = false;
+ var page = this.PageObject;
+ var token = this.ExtractCancellationSource.Token;
+ if (YanderePage.IsYanderePage(page) && !token.IsCancellationRequested)
{
- this.CanExtract = false;
- var page = this.PageObject;
- var token = this.ExtractCancellationSource.Token;
- if (YanderePage.IsYanderePage(page) && !token.IsCancellationRequested)
+ foreach (var nextPage in page)
{
- foreach (var nextPage in page)
- {
- if (token.IsCancellationRequested) { break; }
- this.PageLink = nextPage.PageLink;
- this.ExtractImageLinks();
- }
+ if (token.IsCancellationRequested) { break; }
+ this.PageLink = nextPage.PageLink;
+ this.ExtractImageLinks();
}
- this.CanExtract = true;
}
- }),
- () => this.CanExtract);
- }
-
- ///
- /// 表示取消提取图片链接的命令。
- ///
- public DelegateCommand CancelExtractLinksCommand { get; }
-
- ///
- /// 创建 。
- ///
- /// 。
- private DelegateCommand CreateCancelExtractLinksCommand()
- {
- return new DelegateCommand(
- () =>
- {
- if (this.CanCancelExtract)
- {
- this.ExtractCancellationSource.Cancel();
- this.ExtractCancellationSource = new CancellationTokenSource();
- this.PageObject.Refresh();
- }
- },
- () => this.CanCancelExtract);
- }
-
- ///
- /// 表示复制已提取的图片链接到剪贴板的命令。
- ///
- public DelegateCommand CopyLinksCommand { get; }
-
- ///
- /// 创建 。
- ///
- /// 。
- private DelegateCommand CreateCopyLinksCommand()
- {
- return new DelegateCommand(
- () =>
- {
- if (this.HasImageLinks)
- {
- Clipboard.SetText(this.ImageLinks);
- }
- },
- () => this.HasImageLinks);
+ this.CanExtract = true;
+ }
+ });
}
///
- /// 表示清除已提取的图片链接的命令。
- ///
- public DelegateCommand ClearLinksCommand { get; }
-
- ///
- /// 创建 。
+ /// 取消提取图片链接的异步操作。
///
- /// 。
- private DelegateCommand CreateClearLinksCommand()
+ public void CancelExtract()
{
- return new DelegateCommand(
- () =>
- {
- if (this.HasImageLinks)
- {
- this.ImageLinks = string.Empty;
- }
- },
- () => this.HasImageLinks);
+ if (this.CanCancelExtract)
+ {
+ this.ExtractCancellationSource.Cancel();
+ this.ExtractCancellationSource = new CancellationTokenSource();
+ this.PageObject.Refresh();
+ }
}
///
@@ -243,19 +165,10 @@ protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
case nameof(this.CanExtract):
this.NotifyPropertyChanged(nameof(this.CanCancelExtract));
- this.ExtractLinksCommand.NotifyCanExecuteChanged();
- this.EnumerateExtractLinksCommand.NotifyCanExecuteChanged();
- break;
- case nameof(this.CanCancelExtract):
- this.CancelExtractLinksCommand.NotifyCanExecuteChanged();
break;
case nameof(this.ImageLinks):
this.NotifyPropertyChanged(nameof(this.HasImageLinks));
break;
- case nameof(this.HasImageLinks):
- this.CopyLinksCommand.NotifyCanExecuteChanged();
- this.ClearLinksCommand.NotifyCanExecuteChanged();
- break;
default:
break;
}
diff --git a/YandereLinks/Views/ConsoleWindow.cs b/YandereLinks/Views/ConsoleWindow.cs
index 0e2f23f..5eadc42 100644
--- a/YandereLinks/Views/ConsoleWindow.cs
+++ b/YandereLinks/Views/ConsoleWindow.cs
@@ -37,7 +37,7 @@ public static class ConsoleWindow
///
/// 已提取的图片链接。
///
- private static readonly ICollection ImageLinks = new HashSet();
+ private static readonly HashSet ImageLinks = new HashSet();
///
/// 显示控制台窗口,并传递程序启动参数。
@@ -111,8 +111,8 @@ private static void Run(string[] args)
foreach (var page in pages)
{
- if (enumCount == 0) { ConsoleWindow.ExtractPage(page); }
- else { ConsoleWindow.EnumeratePages(page, enumCount); }
+ if (enumCount == 0) { ConsoleWindow.ExtractImageLinksAsync(page); }
+ else { ConsoleWindow.EnumeratePageExtractAsync(page, enumCount); }
}
while (ConsoleWindow.WorkingThreads != 0) { Thread.Sleep(10); }
@@ -129,6 +129,22 @@ private static void Run(string[] args)
}
}
+ ///
+ /// 将帮助信息输出到控制台。
+ ///
+ private static void ShowHelp()
+ {
+ Console.WriteLine();
+ Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_Usage);
+ Console.WriteLine();
+ Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_PageLink);
+ Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_PageCount);
+ Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_MaxThreads);
+ Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_OutFile);
+ Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_Help);
+ Console.WriteLine();
+ }
+
///
/// 格式化输入的 yande.re 页面链接。
///
@@ -150,27 +166,11 @@ private static string FormatPageLink(string pageLink)
else { return pageLink; }
}
- ///
- /// 将帮助信息输出到控制台。
- ///
- private static void ShowHelp()
- {
- Console.WriteLine();
- Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_Usage);
- Console.WriteLine();
- Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_PageLink);
- Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_PageCount);
- Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_MaxThreads);
- Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_OutFile);
- Console.WriteLine(Properties.StringResources.ConsoleWindow_Help_Help);
- Console.WriteLine();
- }
-
///
/// 提取页面中包含的图片链接。
///
/// 页面连接提取对象。
- private static void ExtractLinks(YanderePage page)
+ private static void ExtractImageLinks(YanderePage page)
{
lock (ConsoleWindow.SyncRoot)
{
@@ -205,26 +205,14 @@ private static void ExtractLinks(YanderePage page)
}
}
- ///
- /// 提取页面中包含的图片链接的线程池回调方法。
- ///
- /// 包含回调方法要使用的信息的对象,
- /// 应为 。
- private static void OnExtractLinks(object state)
- {
- if (state is YanderePage page)
- {
- ConsoleWindow.ExtractLinks(page);
- }
- }
-
///
/// 异步提取页面中包含的图片链接。
///
/// 页面链接提取对象。
- private static void ExtractPage(YanderePage page)
+ private static void ExtractImageLinksAsync(YanderePage page)
{
- ThreadPool.QueueUserWorkItem(ConsoleWindow.OnExtractLinks, page);
+ ThreadPool.QueueUserWorkItem(
+ state => ConsoleWindow.ExtractImageLinks((YanderePage)state), page);
}
///
@@ -233,14 +221,14 @@ private static void ExtractPage(YanderePage page)
/// 页面链接提取对象。
/// 指定遍历的页面数量;
/// 为 -1 则遍历至最后一页,为 0 则不进行遍历。默认为 0。
- private static void EnumeratePages(YanderePage page, int enumCount = -1)
+ private static void EnumeratePageExtractAsync(YanderePage page, int enumCount = -1)
{
enumCount = (enumCount < 0) ?
(page.Count - page.Index + 1) :
((enumCount == 0) ? 1 : enumCount);
for (int i = page.Index; i < page.Index + enumCount; i++)
{
- ConsoleWindow.ExtractPage(page[i]);
+ ConsoleWindow.ExtractImageLinksAsync(page[i]);
}
}
}
diff --git a/YandereLinks/Views/MainWindow.xaml b/YandereLinks/Views/MainWindow.xaml
index b575390..2ff5403 100644
--- a/YandereLinks/Views/MainWindow.xaml
+++ b/YandereLinks/Views/MainWindow.xaml
@@ -9,21 +9,14 @@
Height="720" Width="1280" MinHeight="450" MinWidth="800" WindowStartupLocation="CenterScreen"
Title="{x:Static props:StringResources.MainWindow_Title}" Icon="../Properties/YandereLinks.ico"
Loaded="ThisWindow_Loaded">
-
-
-
-
-
-
-
-
+
@@ -45,19 +38,19 @@
+ Command="{x:Static local:MainWindow.ExtractImageLinksCommand}"/>
+ Command="{x:Static local:MainWindow.EnumeratePageExtractCommand}"/>
+ Command="{x:Static local:MainWindow.CancelExtractCommand}"/>
+ Command="{x:Static local:MainWindow.CopyImageLinksCommand}"/>
+ Command="{x:Static local:MainWindow.ClearImageLinksCommand}"/>
diff --git a/YandereLinks/Views/MainWindow.xaml.cs b/YandereLinks/Views/MainWindow.xaml.cs
index a3cd633..c5adaae 100644
--- a/YandereLinks/Views/MainWindow.xaml.cs
+++ b/YandereLinks/Views/MainWindow.xaml.cs
@@ -1,36 +1,132 @@
using System;
+using System.ComponentModel;
using System.Diagnostics;
using System.Security;
using System.Windows;
+using System.Windows.Input;
using XstarS.Win32;
using XstarS.YandereLinks.ViewModels;
namespace XstarS.YandereLinks.Views
{
///
- /// MainWindow.xaml 的交互逻辑。
+ /// 表示应用程序的主要窗口。
///
public partial class MainWindow : Window
{
///
- /// 初始化 的新实例。
+ /// 初始化 类。
+ ///
+ static MainWindow()
+ {
+ MainWindow.InitializeCommandBindings();
+ }
+
+ ///
+ /// 初始化 类的新实例。
///
public MainWindow()
{
- this.InitializeComponent();
this.DataContext = new MainWindowModel();
+ this.InitializeComponent();
+ this.Model.PropertyChanged += this.Model_PropertyChanged;
}
///
- /// 当前窗口加载完成的事件处理。
+ /// 当前 的数据逻辑模型。
///
- /// 事件源。
- /// 提供事件数据的对象。
- private void ThisWindow_Loaded(object sender, RoutedEventArgs e)
+ public MainWindowModel Model => (MainWindowModel)this.DataContext;
+
+ ///
+ /// 初始化 的命令绑定。
+ ///
+ private static void InitializeCommandBindings()
{
- this.TrySetWebBrowserVersion();
+ var commandBindings = new[]
+ {
+ new CommandBinding(MainWindow.ExtractImageLinksCommand,
+ (sender, e) => ((MainWindow)sender).Model.ExtractImageLinksAsync(),
+ (sender, e) => e.CanExecute = ((MainWindow)sender).Model.CanExtract),
+ new CommandBinding(MainWindow.EnumeratePageExtractCommand,
+ (sender, e) => ((MainWindow)sender).Model.EnumeratePageExtractAsync(),
+ (sender, e) => e.CanExecute = ((MainWindow)sender).Model.CanExtract),
+ new CommandBinding(MainWindow.CancelExtractCommand,
+ (sender, e) => ((MainWindow)sender).Model.CancelExtract(),
+ (sender, e) => e.CanExecute = ((MainWindow)sender).Model.CanCancelExtract),
+ new CommandBinding(MainWindow.CopyImageLinksCommand,
+ (sender, e) => Clipboard.SetText(((MainWindow)sender).Model.ImageLinks),
+ (sender, e) => e.CanExecute = ((MainWindow)sender).Model.HasImageLinks),
+ new CommandBinding(MainWindow.ClearImageLinksCommand,
+ (sender, e) => ((MainWindow)sender).Model.ImageLinks = string.Empty,
+ (sender, e) => e.CanExecute = ((MainWindow)sender).Model.HasImageLinks),
+ };
+
+ foreach (var commandBinding in commandBindings)
+ {
+ CommandManager.RegisterClassCommandBinding(typeof(MainWindow), commandBinding);
+ }
}
+ ///
+ /// 获取表示“提取图片链接”的命令的值。
+ /// 默认键笔势:Ctrl+E。
+ ///
+ public static RoutedUICommand ExtractImageLinksCommand { get; } =
+ new RoutedUICommand(
+ nameof(MainWindow.ExtractImageLinksCommand),
+ nameof(MainWindow.ExtractImageLinksCommand),
+ typeof(MainWindow),
+ new InputGestureCollection() {
+ new KeyGesture(Key.E, ModifierKeys.Control, "Ctrl+E") });
+
+ ///
+ /// 获取表示“遍历页面提取”命令的值。
+ /// 默认键笔势:Ctrl+R。
+ ///
+ public static RoutedUICommand EnumeratePageExtractCommand { get; } =
+ new RoutedUICommand(
+ nameof(MainWindow.EnumeratePageExtractCommand),
+ nameof(MainWindow.EnumeratePageExtractCommand),
+ typeof(MainWindow),
+ new InputGestureCollection() {
+ new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl+R") });
+
+ ///
+ /// 获取表示“取消提取”命令的值。
+ /// 默认键笔势:Ctrl+R。
+ ///
+ public static RoutedUICommand CancelExtractCommand { get; } =
+ new RoutedUICommand(
+ nameof(MainWindow.CancelExtractCommand),
+ nameof(MainWindow.CancelExtractCommand),
+ typeof(MainWindow),
+ new InputGestureCollection() {
+ new KeyGesture(Key.D, ModifierKeys.Control, "Ctrl+D") });
+
+ ///
+ /// 获取表示“复制图片链接”命令的值。
+ /// 默认键笔势:Ctrl+C。
+ ///
+ public static RoutedUICommand CopyImageLinksCommand { get; } =
+ new RoutedUICommand(
+ nameof(MainWindow.CopyImageLinksCommand),
+ nameof(MainWindow.CopyImageLinksCommand),
+ typeof(MainWindow),
+ new InputGestureCollection() {
+ new KeyGesture(Key.C, ModifierKeys.Control, "Ctrl+C") });
+
+ ///
+ /// 获取表示“清除图片链接”命令的值。
+ /// 默认键笔势:Ctrl+X。
+ ///
+ public static RoutedUICommand ClearImageLinksCommand { get; } =
+ new RoutedUICommand(
+ nameof(MainWindow.ClearImageLinksCommand),
+ nameof(MainWindow.ClearImageLinksCommand),
+ typeof(MainWindow),
+ new InputGestureCollection() {
+ new KeyGesture(Key.X, ModifierKeys.Control, "Ctrl+X") });
+
///
/// 尝试将内置网页浏览器的版本设定为当前系统支持的最新版本。
///
@@ -59,5 +155,35 @@ private void TrySetWebBrowserVersion()
MessageBox.Show(ex.GetType().ToString() + Environment.NewLine + ex.Message);
}
}
+
+ ///
+ /// 当前窗口加载完成的事件处理。
+ ///
+ /// 事件源。
+ /// 提供事件数据的对象。
+ private void ThisWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+ this.TrySetWebBrowserVersion();
+ }
+
+ ///
+ /// 当前窗口的数据逻辑模型的属性值更改的事件处理。
+ ///
+ /// 事件源。
+ /// 提供事件数据的对象。
+ private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ switch (e.PropertyName)
+ {
+ case nameof(this.Model.CanExtract):
+ case nameof(this.Model.CanCancelExtract):
+ case nameof(this.Model.HasImageLinks):
+ this.Dispatcher.Invoke(
+ () => CommandManager.InvalidateRequerySuggested());
+ break;
+ default:
+ break;
+ }
+ }
}
}
diff --git a/YandereLinks/Views/NaviWebBrowser.xaml b/YandereLinks/Views/NavigationWebBrowser.xaml
similarity index 96%
rename from YandereLinks/Views/NaviWebBrowser.xaml
rename to YandereLinks/Views/NavigationWebBrowser.xaml
index a684ea4..542e3e0 100644
--- a/YandereLinks/Views/NaviWebBrowser.xaml
+++ b/YandereLinks/Views/NavigationWebBrowser.xaml
@@ -1,4 +1,4 @@
-
/// 表示一个带有导航控件的 。
///
- public partial class NaviWebBrowser : UserControl
+ public partial class NavigationWebBrowser : UserControl
{
///
- /// 初始化 类的新实例。
+ /// 初始化 类。
///
- public NaviWebBrowser()
+ static NavigationWebBrowser()
+ {
+ NavigationWebBrowser.InitializeCommandBindings();
+ }
+
+ ///
+ /// 初始化 类的新实例。
+ ///
+ public NavigationWebBrowser()
{
this.InitializeComponent();
- this.InitializeCommandBindings();
+ this.InitializeComponentCommandBindings();
this.MainWebBrowser.Navigated += this.MainWebBrowser_Navigated;
- this.MainWebBrowser.SuppressScriptErrors(true);
}
///
- /// 初始化当前用户控件的命令绑定。
+ /// 初始化 的命令绑定。
///
- private void InitializeCommandBindings()
+ private static void InitializeCommandBindings()
{
- this.CommandBindings.AddRange(new[]
+ var commandBindings = new[]
{
new CommandBinding(NavigationCommands.BrowseBack,
- (sender, e) => this.GoBack(), (sender, e) => e.CanExecute = this.CanGoBack),
+ (sender, e) => ((NavigationWebBrowser)sender).GoBack(),
+ (sender, e) => e.CanExecute = ((NavigationWebBrowser)sender).CanGoBack),
new CommandBinding(NavigationCommands.BrowseForward,
- (sender, e) => this.GoForward(), (sender, e) => e.CanExecute = this.CanGoForward),
- new CommandBinding(NavigationCommands.BrowseHome, (senders, e) => this.GoHome()),
+ (sender, e) => ((NavigationWebBrowser)sender).GoForward(),
+ (sender, e) => e.CanExecute = ((NavigationWebBrowser)sender).CanGoForward),
+ new CommandBinding(NavigationCommands.BrowseHome,
+ (sender, e) => ((NavigationWebBrowser)sender).GoHome()),
new CommandBinding(NavigationCommands.GoToPage,
- (sender, e) => this.Navigate(e.Parameter as string)),
- new CommandBinding(NavigationCommands.Refresh, (sender, e) => this.Refresh()),
- });
+ (sender, e) => ((NavigationWebBrowser)sender).Navigate(e.Parameter as string)),
+ new CommandBinding(NavigationCommands.Refresh,
+ (sender, e) => ((NavigationWebBrowser)sender).Refresh()),
+ };
+
+ foreach (var commandBinding in commandBindings)
+ {
+ CommandManager.RegisterClassCommandBinding(typeof(NavigationWebBrowser), commandBinding);
+ }
+ }
+
+ ///
+ /// 初始化当前 所包含的组件的命令绑定。
+ ///
+ private void InitializeComponentCommandBindings()
+ {
this.SourceTextBox.CommandBindings.AddRange(new[]
{
new CommandBinding(EditingCommands.EnterParagraphBreak,
@@ -47,61 +69,61 @@ private void InitializeCommandBindings()
}
///
- /// 表示 的依赖属性。
+ /// 表示 的依赖属性。
///
public static readonly DependencyProperty CanGoBackProperty =
- DependencyProperty.Register(nameof(NaviWebBrowser.CanGoBack),
- typeof(bool), typeof(NaviWebBrowser), new PropertyMetadata(false));
+ DependencyProperty.Register(nameof(NavigationWebBrowser.CanGoBack),
+ typeof(bool), typeof(NavigationWebBrowser), new PropertyMetadata(false));
+
+ ///
+ /// 后退到前一页面。
+ ///
+ public void GoBack() => this.MainWebBrowser.GoBack();
///
/// 指示是否可以后退到前一页面。
///
public bool CanGoBack
{
- get => (bool)this.GetValue(NaviWebBrowser.CanGoBackProperty);
- private set => this.SetValue(NaviWebBrowser.CanGoBackProperty, value);
+ get => (bool)this.GetValue(NavigationWebBrowser.CanGoBackProperty);
+ private set => this.SetValue(NavigationWebBrowser.CanGoBackProperty, value);
}
///
- /// 后退到前一页面。
+ /// 表示 的依赖属性。
///
- public void GoBack() => this.MainWebBrowser.GoBack();
+ public static readonly DependencyProperty CanGoForwardProperty =
+ DependencyProperty.Register(nameof(NavigationWebBrowser.CanGoForward),
+ typeof(bool), typeof(NavigationWebBrowser), new PropertyMetadata(false));
///
- /// 表示 的依赖属性。
+ /// 前进到下一页面。
///
- public static readonly DependencyProperty CanGoForwardProperty =
- DependencyProperty.Register(nameof(NaviWebBrowser.CanGoForward),
- typeof(bool), typeof(NaviWebBrowser), new PropertyMetadata(false));
+ public void GoForward() => this.MainWebBrowser.GoForward();
///
/// 指示是否可以前进到下一页面。
///
public bool CanGoForward
{
- get => (bool)this.GetValue(NaviWebBrowser.CanGoForwardProperty);
- private set => this.SetValue(NaviWebBrowser.CanGoForwardProperty, value);
+ get => (bool)this.GetValue(NavigationWebBrowser.CanGoForwardProperty);
+ private set => this.SetValue(NavigationWebBrowser.CanGoForwardProperty, value);
}
///
- /// 前进到下一页面。
- ///
- public void GoForward() => this.MainWebBrowser.GoForward();
-
- ///
- /// 表示 的依赖属性。
+ /// 表示 的依赖属性。
///
public static readonly DependencyProperty HomeSourceProperty =
- DependencyProperty.Register(nameof(NaviWebBrowser.HomeSource),
- typeof(string), typeof(NaviWebBrowser), new PropertyMetadata(string.Empty));
+ DependencyProperty.Register(nameof(NavigationWebBrowser.HomeSource),
+ typeof(string), typeof(NavigationWebBrowser), new PropertyMetadata(string.Empty));
///
/// 获取主页的链接文本。
///
public string HomeSource
{
- get => (string)this.GetValue(NaviWebBrowser.HomeSourceProperty);
- set => this.SetValue(NaviWebBrowser.HomeSourceProperty, value);
+ get => (string)this.GetValue(NavigationWebBrowser.HomeSourceProperty);
+ set => this.SetValue(NavigationWebBrowser.HomeSourceProperty, value);
}
///
@@ -110,22 +132,22 @@ public string HomeSource
public void GoHome() => this.MainWebBrowser.Navigate(this.HomeSource);
///
- /// 表示 的依赖属性。
+ /// 表示 的依赖属性。
///
public static readonly DependencyProperty SourceProperty =
- DependencyProperty.Register(nameof(NaviWebBrowser.Source),
- typeof(string), typeof(NaviWebBrowser), new PropertyMetadata(string.Empty,
- NaviWebBrowser.SourceProperty_PropertyChanged));
+ DependencyProperty.Register(nameof(NavigationWebBrowser.Source),
+ typeof(string), typeof(NavigationWebBrowser), new PropertyMetadata(string.Empty,
+ NavigationWebBrowser.OnSourcePropertyChanged));
///
- /// 依赖属性发生更改的事件处理。
+ /// 依赖属性发生更改的事件处理。
///
- /// 包含依赖属性的 。
+ /// 包含依赖属性的 。
/// 提供事件数据的对象。
- private static void SourceProperty_PropertyChanged(
+ private static void OnSourcePropertyChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- if ((d is NaviWebBrowser navi) && (e.NewValue is string source))
+ if ((d is NavigationWebBrowser navi) && (e.NewValue is string source))
{
if (navi.MainWebBrowser.Source?.OriginalString != source)
{
@@ -139,8 +161,18 @@ public string HomeSource
///
public string Source
{
- get => (string)this.GetValue(NaviWebBrowser.SourceProperty);
- set => this.SetValue(NaviWebBrowser.SourceProperty, value);
+ get => (string)this.GetValue(NavigationWebBrowser.SourceProperty);
+ set => this.SetValue(NavigationWebBrowser.SourceProperty, value);
+ }
+
+ ///
+ /// 显式更新链接文本框的数据源。
+ ///
+ private void ExplicitUpdateSource()
+ {
+ this.SourceTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
+ this.MainWebBrowser.Navigate(this.Source);
+ this.MainWebBrowser.Focus();
}
///
@@ -180,16 +212,6 @@ public string Source
remove => this.MainWebBrowser.LoadCompleted -= value;
}
- ///
- /// 显式更新链接文本框的数据源。
- ///
- private void ExplicitUpdateSource()
- {
- this.SourceTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
- this.MainWebBrowser.Navigate(this.Source);
- this.MainWebBrowser.Focus();
- }
-
///
/// 网页浏览器导航完成的事件处理。
///
@@ -200,7 +222,8 @@ private void MainWebBrowser_Navigated(object sender, NavigationEventArgs e)
this.CanGoBack = this.MainWebBrowser.CanGoBack;
this.CanGoForward = this.MainWebBrowser.CanGoForward;
this.Source = this.MainWebBrowser.Source?.OriginalString;
- CommandManager.InvalidateRequerySuggested();
+ this.Dispatcher.Invoke(
+ () => CommandManager.InvalidateRequerySuggested());
}
}
}
diff --git a/YandereLinks/YandereLinks.csproj b/YandereLinks/YandereLinks.csproj
index 7b2884a..a550c34 100644
--- a/YandereLinks/YandereLinks.csproj
+++ b/YandereLinks/YandereLinks.csproj
@@ -62,8 +62,6 @@
MSBuild:Compile
Designer
-
-
True
True
@@ -74,12 +72,11 @@
True
Settings.settings
-
- NaviWebBrowser.xaml
+
+ NavigationWebBrowser.xaml
-
@@ -100,7 +97,7 @@
MainWindow.xaml
Code
-
+
Designer
MSBuild:Compile