Imports System.Windows.Threading Public Class PageLaunchRight Implements IRefreshable, IDispatcherUnhandledException Private Sub Init() Handles Me.Loaded PanBack.ScrollToHome() CommunismWelcome.Visibility = If(ThemeNow = DefaultTheme, Visibility.Visible, Visibility.Collapsed) PanLog.Visibility = ModeDebug.ToVisibility '快照版提示 PanHint.Visibility = (BuildType <> BuildTypes.Release AndAlso VersionBranchMain = "Official" AndAlso CurrentRank < DonationRank.Rank23 AndAlso Not Settings.Get(Of Boolean)("HintSnapshot")).ToVisibility End Sub Private Sub BtnRedDownload_Click(sender As Object, e As EventArgs) Handles BtnRedDownload.Click FrmMain.PageChange(FormMain.PageType.Download) End Sub Private Sub BtnRedThemes_Click(sender As Object, e As EventArgs) Handles BtnRedThemes.Click FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupUI) End Sub #Region "主页" ''' ''' 刷新主页。 ''' Private Sub Refresh() Handles Me.Loaded RunInThread( Sub() Try SyncLock RefreshLock RefreshReal() End SyncLock Catch ex As Exception Logger.Error(ex, "加载 PCL 主页自定义信息失败", If(ModeDebug, LogBehavior.Alert, LogBehavior.Toast)) End Try End Sub) End Sub Private Sub RefreshReal() Dim Content As String = Nothing If Settings.Get(Of Integer)("UiCustomType") = 1 Then Content = FileUtils.TryReadAsString(Paths.Base & "PCL\Custom.xaml") ElseIf Settings.Get(Of Integer)("UiCustomType") = 3 Then Content = "" End If RunInUi(Sub() LoadContent(Content)) End Sub Private RefreshLock As New Object Public Sub ForceRefresh() Implements IRefreshable.Refresh Logger.Info("要求强制刷新主页") ClearCache() '实际的刷新 If FrmMain.PageCurrent.Page = FormMain.PageType.Launch Then PanBack.ScrollToHome() Refresh() Else FrmMain.PageChange(FormMain.PageType.Launch) End If End Sub ''' ''' 清空主页缓存信息。 ''' Private Sub ClearCache() LoadedContentHash = Nothing Settings.Set("CacheSavedPageUrl", "") Settings.Set("CacheSavedPageVersion", "") Logger.Info("已清空主页缓存") End Sub ''' ''' 从文本内容中加载主页。 ''' 必须在 UI 线程调用。 ''' Private Sub LoadContent(Content As String) Try SyncLock LoadContentLock '如果加载目标内容一致则不加载 Dim Hash = If(Content, "").GetStableHashCode() If Hash = LoadedContentHash Then Return LoadedContentHash = Hash '实际加载内容 PanCustom.Children.Clear() If String.IsNullOrWhiteSpace(Content) Then Logger.Info($"实例化:清空主页 UI,来源为空") Return End If Dim LoadStartTime As Date = Date.Now '修改时应同时修改 PageOtherHelpDetail.Init Content = ArgumentReplace(Content, AddressOf StringUtils.XmlEscape) Do While Content.Contains("xmlns") Content = Content.RegexReplace("xmlns[^""']*(""|')[^""']*(""|')", "").Replace("xmlns", "") '禁止声明命名空间 Loop Content = "" & Content & "" Logger.Info($"实例化:加载主页 UI 开始,最终内容长度:{Content.Count}") PanCustom.Children.Add(GetObjectFromXML(Content)) '加载计时 Dim LoadCostTime = (Date.Now - LoadStartTime).Milliseconds Logger.Info($"实例化:加载主页 UI 完成,耗时 {LoadCostTime}ms") If LoadCostTime > 3000 Then Hint($"主页加载过于缓慢(花费了 {Math.Round(LoadCostTime / 1000, 1)} 秒),请向主页作者反馈此问题,或暂时停止使用该主页") End SyncLock Catch ex As Exception Logger.Warn(ex, $"加载失败的主页内容:{vbCrLf}{Content}") OnLoadContentFailed(ex) End Try End Sub ''' ''' 加载主页失败时调用。 ''' Private Sub OnLoadContentFailed(ex As Exception) If ModeDebug OrElse Settings.Get(Of Integer)("UiCustomType") = 1 Then Logger.Warn(ex, "加载主页失败") If MyMsgBox(If(TypeOf ex Is UnauthorizedAccessException, ex.Message, $"主页内容编写有误,请根据下列错误信息进行检查:{vbCrLf}{ex.GetDisplay(False)}"), "加载主页失败", "重试", "取消") = 1 Then ForceRefresh() Else Logger.Error(ex, "加载主页失败", LogBehavior.Toast) End If End Sub ''' ''' 捕获主页在 Measure 和 Arrange 阶段抛出的异常。 ''' Private Sub DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Implements IDispatcherUnhandledException.DispatcherUnhandledException If TypeOf e.Exception IsNot Markup.XamlParseException Then Return e.Handled = True LoadContent(Nothing) OnLoadContentFailed(e.Exception) End Sub Private LoadedContentHash As ULong? = Nothing Private LoadContentLock As New Object #End Region End Class