当前位置: 首页 > news >正文

.NET 6 WPF 利用CefSharp.Wpf.NETCore显示PDF文件

在WPF程序中,我们可以有多种方式显示PDF文件,但是目前发现的性能最好的是CefSharp.Wpf.NETCore。

CefSharp.Wpf.NETCore是一款开源软件。https://github.com/cefsharp/CefSharp。

它提供了WPF版本和WinForm版本,可根据自己的需要进行安装。

本文介绍基于.NET 6 版本的WPF如何使用CefSharp.Wpf.NETCore。

目录

1. 通过NuGet安装CefSharp.Wpf.NETCore

2. 在App.xaml.cs中注册CefSharp.Wpf.NETCore

3. 创建自定义控件

3.1 UCPDFViewer.xaml

3.2 UCPDFViewer.xaml.cs

3.3 ValueConvert-BooleanToVisibilityConverter

3.4 ValueConvert- EnvironmentConverter 

4. 使用自定义控件


1. 通过NuGet安装CefSharp.Wpf.NETCore

WPF程序中通过NuGet packages安装CefSharp.Wpf.NETCore。找到自己需要的版本。本文用的版本号是98.1.210

2. 在App.xaml.cs中注册CefSharp.Wpf.NETCore

1. 构造函数中进行初始化

2. 程序退出时销毁

using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using CefSharp;
using CefSharp.Wpf;namespace MyWpf.UI
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App : Application{#region Ctorpublic App(){SetCefSettings();}#endregionprivate void Application_Exit(object sender, ExitEventArgs e){Cef.Shutdown();}#region CefSharp Settingprivate void SetCefSettings(){
#if ANYCPU//Only required for PlatformTarget of AnyCPUCefRuntime.SubscribeAnyCpuAssemblyResolver();
#endifvar settings = new CefSettings(){//By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist dataCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"),IgnoreCertificateErrors = true};//Example of setting a command line argument//Enables WebRTC// - CEF Doesn't currently support permissions on a per browser basis see https://bitbucket.org/chromiumembedded/cef/issues/2582/allow-run-time-handling-of-media-access// - CEF Doesn't currently support displaying a UI for media access permissions////NOTE: WebRTC Device Id's aren't persisted as they are in Chrome see https://bitbucket.org/chromiumembedded/cef/issues/2064/persist-webrtc-deviceids-across-restartsettings.CefCommandLineArgs.Add("enable-media-stream");//https://peter.sh/experiments/chromium-command-line-switches/#use-fake-ui-for-media-streamsettings.CefCommandLineArgs.Add("use-fake-ui-for-media-stream");//For screen sharing add (see https://bitbucket.org/chromiumembedded/cef/issues/2582/allow-run-time-handling-of-media-access#comment-58677180)settings.CefCommandLineArgs.Add("enable-usermedia-screen-capturing");//Example of checking if a call to Cef.Initialize has already been made, we require this for//our .Net 5.0 Single File Publish example, you don't typically need to perform this check//if you call Cef.Initialze within your WPF App constructor.if (!Cef.IsInitialized){//Perform dependency check to make sure all relevant resources are in our output directory.Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);}}#endregion}
}

3. 创建自定义控件

创建UCPDFViewer.

3.1 UCPDFViewer.xaml

<UserControl x:Class="MyWpf.UI.Views.CustomControls.UCPDFViewer"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:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf" xmlns:cef="clr-namespace:CefSharp;assembly=CefSharp.Core" xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"xmlns:vc="clr-namespace:Cortland.Agency.UI.ValueConverters" xmlns:local="clr-namespace:MyWpf.UI.Views.CustomControls"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><UserControl.Resources><ResourceDictionary><vc:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/><vc:EnvironmentConverter x:Key="EnvironmentConverter"></vc:EnvironmentConverter></ResourceDictionary></UserControl.Resources><Grid><Grid.RowDefinitions><RowDefinition/><RowDefinition Height="Auto" /></Grid.RowDefinitions><Border Grid.Row="0" BorderBrush="Gray" BorderThickness="0,1"><wpf:ChromiumWebBrowser x:Name="Browser"></wpf:ChromiumWebBrowser></Border><ProgressBar Grid.Row="1" IsIndeterminate="{Binding IsLoading, ElementName=Browser}"HorizontalAlignment="Stretch"VerticalAlignment="Top"Width="Auto" Foreground="{StaticResource ADBrandOrangeBrush}"Height="5" Visibility="{Binding IsLoading, ElementName=Browser, Converter={StaticResource BooleanToVisibilityConverter}}"BorderThickness="0" /></Grid>
</UserControl>

3.2 UCPDFViewer.xaml.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CefSharp;
using log4net;namespace MyWpf.UI.Views.CustomControls
{/// <summary>/// Interaction logic for UCPDFViewer.xaml/// </summary>public partial class UCPDFViewer : UserControl{private string inputCurrentFilePath = "";private const int Max_ReTryTime = 3;private int reTryTime;public bool IsLoaded { get; set; }public delegate void LoadFileErrorEventHandler(ActionResultCollection validationRules);public event LoadFileErrorEventHandler LoadFileErrorEvent;private static readonly ILog Log = LogManager.GetLogger(typeof(UCPDFViewer));public UCPDFViewer(){InitializeComponent();this.Loaded -= UCPDFViewer_Loaded;this.Loaded += UCPDFViewer_Loaded;this.Unloaded -= UCPDFViewer_Unloaded;this.Unloaded += UCPDFViewer_Unloaded;}public void UCPDFViewer_Unloaded(object sender, RoutedEventArgs e){try{Log.Debug("UCPDFViewer_Unloaded Start.");if (Browser != null){Browser.Dispose();}}catch (Exception ex){Log.Error($"UCPDFViewer_Unloaded Error.{ex.Message}", ex);}finally{Log.Debug("UCPDFViewer_Unloaded End.");}}private void UCPDFViewer_Loaded(object sender, RoutedEventArgs e){Browser.LoadError -= Browser_LoadError;Browser.Loaded -= Browser_Loaded;Browser.LoadError += Browser_LoadError;Browser.Loaded += Browser_Loaded;}private void Browser_Loaded(object sender, RoutedEventArgs e){reTryTime = 0;this.IsLoaded = true;}/// <summary>/// file://192.168.0.110/AgencyTeam/%23%23Files%23%23/AgencyFiles/02387e57-0cb1-4a3c-a4cc-d5f639f85d70/-001%20FAC-402550.pdf/// </summary>/// <param name="filePath"></param>public void LoadUrl(string filePath){this.IsLoaded = false;string convertedFilePath = filePath;if (!filePath.StartsWith("file://")){convertedFilePath = new Uri(filePath).AbsoluteUri;}inputCurrentFilePath = convertedFilePath;Browser.Load(convertedFilePath);}private void Browser_LoadError(object sender, CefSharp.LoadErrorEventArgs e){if (reTryTime >= Max_ReTryTime){var validationRules = new ActionResultCollection();var wrongData = new ValidationActionResult(){IsValid = false,Message = string.Format(ValidationFailureConstants.JOBTICKET_PDF_LOAD_FAILED, e.ErrorCode.ToString())};validationRules.Add(wrongData);LoadFileErrorEvent?.Invoke(validationRules);IsLoaded = false;return;}reTryTime += 1;switch (e.ErrorCode){case CefSharp.CefErrorCode.None:break;case CefSharp.CefErrorCode.IoPending:break;case CefSharp.CefErrorCode.Failed:break;case CefSharp.CefErrorCode.Aborted:break;case CefSharp.CefErrorCode.InvalidArgument:break;case CefSharp.CefErrorCode.InvalidHandle:break;case CefSharp.CefErrorCode.FileNotFound:LoadUrl(this.inputCurrentFilePath);break;case CefSharp.CefErrorCode.TimedOut:break;case CefSharp.CefErrorCode.FileTooBig:break;case CefSharp.CefErrorCode.Unexpected:break;case CefSharp.CefErrorCode.AccessDenied:break;case CefSharp.CefErrorCode.NotImplemented:break;case CefSharp.CefErrorCode.InsufficientResources:break;case CefSharp.CefErrorCode.OutOfMemory:break;case CefSharp.CefErrorCode.UploadFileChanged:break;case CefSharp.CefErrorCode.SocketNotConnected:break;case CefSharp.CefErrorCode.FileExists:break;case CefSharp.CefErrorCode.FilePathTooLong:break;case CefSharp.CefErrorCode.FileNoSpace:break;case CefSharp.CefErrorCode.FileVirusInfected:break;case CefSharp.CefErrorCode.BlockedByClient:break;case CefSharp.CefErrorCode.NetworkChanged:break;case CefSharp.CefErrorCode.BlockedByAdministrator:break;case CefSharp.CefErrorCode.SocketIsConnected:break;case CefSharp.CefErrorCode.UploadStreamRewindNotSupported:break;case CefSharp.CefErrorCode.ContextShutDown:break;case CefSharp.CefErrorCode.BlockedByResponse:break;case CefSharp.CefErrorCode.CleartextNotPermitted:break;case CefSharp.CefErrorCode.ConnectionClosed:break;case CefSharp.CefErrorCode.ConnectionReset:break;case CefSharp.CefErrorCode.ConnectionRefused:break;case CefSharp.CefErrorCode.ConnectionAborted:break;case CefSharp.CefErrorCode.ConnectionFailed:break;case CefSharp.CefErrorCode.NameNotResolved:break;case CefSharp.CefErrorCode.InternetDisconnected:break;case CefSharp.CefErrorCode.SslProtocolError:break;case CefSharp.CefErrorCode.AddressInvalid:LoadUrl(this.inputCurrentFilePath);break;case CefSharp.CefErrorCode.AddressUnreachable:break;case CefSharp.CefErrorCode.SslClientAuthCertNeeded:break;case CefSharp.CefErrorCode.TunnelConnectionFailed:break;case CefSharp.CefErrorCode.NoSslVersionsEnabled:break;case CefSharp.CefErrorCode.SslVersionOrCipherMismatch:break;case CefSharp.CefErrorCode.SslRenegotiationRequested:break;case CefSharp.CefErrorCode.ProxyAuthUnsupported:break;case CefSharp.CefErrorCode.BadSslClientAuthCert:break;case CefSharp.CefErrorCode.ConnectionTimedOut:break;case CefSharp.CefErrorCode.HostResolverQueueTooLarge:break;case CefSharp.CefErrorCode.SocksConnectionFailed:break;case CefSharp.CefErrorCode.SocksConnectionHostUnreachable:break;case CefSharp.CefErrorCode.AlpnNegotiationFailed:break;case CefSharp.CefErrorCode.SslNoRenegotiation:break;case CefSharp.CefErrorCode.WinsockUnexpectedWrittenBytes:break;case CefSharp.CefErrorCode.SslDecompressionFailureAlert:break;case CefSharp.CefErrorCode.SslBadRecordMacAlert:break;case CefSharp.CefErrorCode.ProxyAuthRequested:break;case CefSharp.CefErrorCode.ProxyConnectionFailed:break;case CefSharp.CefErrorCode.MandatoryProxyConfigurationFailed:break;case CefSharp.CefErrorCode.PreconnectMaxSocketLimit:break;case CefSharp.CefErrorCode.SslClientAuthPrivateKeyAccessDenied:break;case CefSharp.CefErrorCode.SslClientAuthCertNoPrivateKey:break;case CefSharp.CefErrorCode.ProxyCertificateInvalid:break;case CefSharp.CefErrorCode.NameResolutionFailed:break;case CefSharp.CefErrorCode.NetworkAccessDenied:break;case CefSharp.CefErrorCode.TemporarilyThrottled:break;case CefSharp.CefErrorCode.HttpsProxyTunnelResponseRedirect:break;case CefSharp.CefErrorCode.SslClientAuthSignatureFailed:break;case CefSharp.CefErrorCode.MsgTooBig:break;case CefSharp.CefErrorCode.WsProtocolError:break;case CefSharp.CefErrorCode.AddressInUse:break;case CefSharp.CefErrorCode.SslHandshakeNotCompleted:break;case CefSharp.CefErrorCode.SslBadPeerPublicKey:break;case CefSharp.CefErrorCode.SslPinnedKeyNotInCertChain:break;case CefSharp.CefErrorCode.ClientAuthCertTypeUnsupported:break;case CefSharp.CefErrorCode.SslDecryptErrorAlert:break;case CefSharp.CefErrorCode.WsThrottleQueueTooLarge:break;case CefSharp.CefErrorCode.SslServerCertChanged:break;case CefSharp.CefErrorCode.SslUnrecognizedNameAlert:break;case CefSharp.CefErrorCode.SocketSetReceiveBufferSizeError:break;case CefSharp.CefErrorCode.SocketSetSendBufferSizeError:break;case CefSharp.CefErrorCode.SocketReceiveBufferSizeUnchangeable:break;case CefSharp.CefErrorCode.SocketSendBufferSizeUnchangeable:break;case CefSharp.CefErrorCode.SslClientAuthCertBadFormat:break;case CefSharp.CefErrorCode.ICANNNameCollision:break;case CefSharp.CefErrorCode.SslServerCertBadFormat:break;case CefSharp.CefErrorCode.CtSthParsingFailed:break;case CefSharp.CefErrorCode.CtSthIncomplete:break;case CefSharp.CefErrorCode.UnableToReuseConnectionForProxyAuth:break;case CefSharp.CefErrorCode.CtConsistencyProofParsingFailed:break;case CefSharp.CefErrorCode.SslObsoleteCipher:break;case CefSharp.CefErrorCode.WsUpgrade:break;case CefSharp.CefErrorCode.ReadIfReadyNotImplemented:break;case CefSharp.CefErrorCode.NoBufferSpace:break;case CefSharp.CefErrorCode.SslClientAuthNoCommonAlgorithms:break;case CefSharp.CefErrorCode.EarlyDataRejected:break;case CefSharp.CefErrorCode.WrongVersionOnEarlyData:break;case CefSharp.CefErrorCode.Tls13DowngradeDetected:break;case CefSharp.CefErrorCode.SslKeyUsageIncompatible:break;case CefSharp.CefErrorCode.CertCommonNameInvalid:break;case CefSharp.CefErrorCode.CertDateInvalid:break;case CefSharp.CefErrorCode.CertAuthorityInvalid:break;case CefSharp.CefErrorCode.CertContainsErrors:break;case CefSharp.CefErrorCode.CertNoRevocationMechanism:break;case CefSharp.CefErrorCode.CertUnableToCheckRevocation:break;case CefSharp.CefErrorCode.CertRevoked:break;case CefSharp.CefErrorCode.CertInvalid:break;case CefSharp.CefErrorCode.CertWeakSignatureAlgorithm:break;case CefSharp.CefErrorCode.CertNonUniqueName:break;case CefSharp.CefErrorCode.CertWeakKey:break;case CefSharp.CefErrorCode.CertNameConstraintViolation:break;case CefSharp.CefErrorCode.CertValidityTooLong:break;case CefSharp.CefErrorCode.CertificateTransparencyRequired:break;case CefSharp.CefErrorCode.CertSymantecLegacy:break;case CefSharp.CefErrorCode.CertKnownInterceptionBlocked:break;case CefSharp.CefErrorCode.CertEnd:break;case CefSharp.CefErrorCode.InvalidUrl:break;case CefSharp.CefErrorCode.DisallowedUrlScheme:break;case CefSharp.CefErrorCode.UnknownUrlScheme:break;case CefSharp.CefErrorCode.TooManyRedirects:break;case CefSharp.CefErrorCode.UnsafeRedirect:break;case CefSharp.CefErrorCode.UnsafePort:break;case CefSharp.CefErrorCode.InvalidResponse:break;case CefSharp.CefErrorCode.InvalidChunkedEncoding:break;case CefSharp.CefErrorCode.MethodNotSupported:break;case CefSharp.CefErrorCode.UnexpectedProxyAuth:break;case CefSharp.CefErrorCode.EmptyResponse:break;case CefSharp.CefErrorCode.ResponseHeadersTooBig:break;case CefSharp.CefErrorCode.PacScriptFailed:break;case CefSharp.CefErrorCode.RequestRangeNotSatisfiable:break;case CefSharp.CefErrorCode.MalformedIdentity:break;case CefSharp.CefErrorCode.ContentDecodingFailed:break;case CefSharp.CefErrorCode.NetworkIoSuspended:break;case CefSharp.CefErrorCode.SynReplyNotReceived:break;case CefSharp.CefErrorCode.EncodingConversionFailed:break;case CefSharp.CefErrorCode.UnrecognizedFtpDirectoryListingFormat:break;case CefSharp.CefErrorCode.NoSupportedProxies:break;case CefSharp.CefErrorCode.Http2ProtocolError:break;case CefSharp.CefErrorCode.InvalidAuthCredentials:break;case CefSharp.CefErrorCode.UnsupportedAuthScheme:break;case CefSharp.CefErrorCode.EncodingDetectionFailed:break;case CefSharp.CefErrorCode.MissingAuthCredentials:break;case CefSharp.CefErrorCode.UnexpectedSecurityLibraryStatus:break;case CefSharp.CefErrorCode.MisconfiguredAuthEnvironment:break;case CefSharp.CefErrorCode.UndocumentedSecurityLibraryStatus:break;case CefSharp.CefErrorCode.ResponseBodyTooBigToDrain:break;case CefSharp.CefErrorCode.ResponseHeadersMultipleContentLength:break;case CefSharp.CefErrorCode.IncompleteHttp2Headers:break;case CefSharp.CefErrorCode.PacNotInDhcp:break;case CefSharp.CefErrorCode.ResponseHeadersMultipleContentDisposition:break;case CefSharp.CefErrorCode.ResponseHeadersMultipleLocation:break;case CefSharp.CefErrorCode.Http2ServerRefusedStream:break;case CefSharp.CefErrorCode.Http2PingFailed:break;case CefSharp.CefErrorCode.ContentLengthMismatch:break;case CefSharp.CefErrorCode.IncompleteChunkedEncoding:break;case CefSharp.CefErrorCode.QuicProtocolError:break;case CefSharp.CefErrorCode.ResponseHeadersTruncated:break;case CefSharp.CefErrorCode.QuicHandshakeFailed:break;case CefSharp.CefErrorCode.Http2InadequateTransportSecurity:break;case CefSharp.CefErrorCode.Http2FlowControlError:break;case CefSharp.CefErrorCode.Http2FrameSizeError:break;case CefSharp.CefErrorCode.Http2CompressionError:break;case CefSharp.CefErrorCode.ProxyAuthRequestedWithNoConnection:break;case CefSharp.CefErrorCode.Http11Required:break;case CefSharp.CefErrorCode.ProxyHttp11Required:break;case CefSharp.CefErrorCode.PacScriptTerminated:break;case CefSharp.CefErrorCode.InvalidHttpResponse:break;case CefSharp.CefErrorCode.ContentDecodingInitFailed:break;case CefSharp.CefErrorCode.Http2RstStreamNoErrorReceived:break;case CefSharp.CefErrorCode.TooManyRetries:break;case CefSharp.CefErrorCode.Http2StreamClosed:break;case CefSharp.CefErrorCode.HttpResponseCodeFailure:break;case CefSharp.CefErrorCode.QuicCertRootNotKnown:break;case CefSharp.CefErrorCode.CacheMiss:break;case CefSharp.CefErrorCode.CacheReadFailure:break;case CefSharp.CefErrorCode.CacheWriteFailure:break;case CefSharp.CefErrorCode.CacheOperationNotSupported:break;case CefSharp.CefErrorCode.CacheOpenFailure:break;case CefSharp.CefErrorCode.CacheCreateFailure:break;case CefSharp.CefErrorCode.CacheRace:break;case CefSharp.CefErrorCode.CacheChecksumReadFailure:break;case CefSharp.CefErrorCode.CacheChecksumMismatch:break;case CefSharp.CefErrorCode.CacheLockTimeout:break;case CefSharp.CefErrorCode.CacheAuthFailureAfterRead:break;case CefSharp.CefErrorCode.CacheEntryNotSuitable:break;case CefSharp.CefErrorCode.CacheDoomFailure:break;case CefSharp.CefErrorCode.CacheOpenOrCreateFailure:break;case CefSharp.CefErrorCode.InsecureResponse:break;case CefSharp.CefErrorCode.NoPrivateKeyForCert:break;case CefSharp.CefErrorCode.AddUserCertFailed:break;case CefSharp.CefErrorCode.InvalidSignedExchange:break;case CefSharp.CefErrorCode.InvalidWebBundle:break;case CefSharp.CefErrorCode.FtpFailed:break;case CefSharp.CefErrorCode.FtpServiceUnavailable:break;case CefSharp.CefErrorCode.FtpTransferAborted:break;case CefSharp.CefErrorCode.FtpFileBusy:break;case CefSharp.CefErrorCode.FtpSyntaxError:break;case CefSharp.CefErrorCode.FtpCommandNotSupported:break;case CefSharp.CefErrorCode.FtpBadCommandSequence:break;case CefSharp.CefErrorCode.Pkcs12ImportBadPassword:break;case CefSharp.CefErrorCode.Pkcs12ImportFailed:break;case CefSharp.CefErrorCode.ImportCaCertNotCa:break;case CefSharp.CefErrorCode.ImportCertAlreadyExists:break;case CefSharp.CefErrorCode.ImportCaCertFailed:break;case CefSharp.CefErrorCode.ImportServerCertFailed:break;case CefSharp.CefErrorCode.Pkcs12ImportInvalidMac:break;case CefSharp.CefErrorCode.Pkcs12ImportInvalidFile:break;case CefSharp.CefErrorCode.Pkcs12ImportUnsupported:break;case CefSharp.CefErrorCode.KeyGenerationFailed:break;case CefSharp.CefErrorCode.PrivateKeyExportFailed:break;case CefSharp.CefErrorCode.SelfSignedCertGenerationFailed:break;case CefSharp.CefErrorCode.CertDatabaseChanged:break;case CefSharp.CefErrorCode.DnsMalformedResponse:break;case CefSharp.CefErrorCode.DnsServerRequiresTcp:break;case CefSharp.CefErrorCode.DnsServerFailed:break;case CefSharp.CefErrorCode.DnsTimedOut:break;case CefSharp.CefErrorCode.DnsCacheMiss:break;case CefSharp.CefErrorCode.DnsSearchEmpty:break;case CefSharp.CefErrorCode.DnsSortError:break;case CefSharp.CefErrorCode.DnsSecureResolverHostnameResolutionFailed:break;default:break;}}}
}

3.3 ValueConvert-BooleanToVisibilityConverter

    public class BooleanToVisibilityConverter : IValueConverter{#region IValueConverter Memberspublic object Convert(object value, Type targetType, object parameter,CultureInfo culture){if (value is Boolean){bool reverse = GetReverseVisibility(parameter);if (reverse){return ((bool)value) ? Visibility.Collapsed : Visibility.Visible;}return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;}return value;}public object ConvertBack(object value, Type targetType, object parameter,CultureInfo culture){if (value is Visibility){bool reverse = GetReverseVisibility(parameter);if (reverse){return ((Visibility)value) == Visibility.Collapsed;}return ((Visibility)value) == Visibility.Visible;}return value;}#endregion#region Helper Methodsprivate bool GetReverseVisibility(object parameter){if (parameter != null && parameter.ToString().ToLower() == "true"){return true;}return false;}#endregion}

3.4 ValueConvert- EnvironmentConverter 

    public class EnvironmentConverter : IValueConverter{object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture){return Environment.Is64BitProcess ? "x64" : "x86";}object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return Binding.DoNothing;}}

4. 使用自定义控件

 xmlns:CustomControls="clr-namespace:Cortland.Agency.UI.Views.CustomControls" <!--<WebBrowser x:Name="webBrowser" Grid.Row="0"/>--><CustomControls:UCPDFViewer x:Name="webBrowser" Grid.Row="0"></CustomControls:UCPDFViewer>
     var fileUrl = new Uri(newFile);webBrowser.LoadUrl(fileUrl.AbsoluteUri);webBrowser.LoadFileErrorEvent -= WebBrowser_LoadFileErrorEvent;webBrowser.LoadFileErrorEvent += WebBrowser_LoadFileErrorEvent;

Track errors when loadin failed. 

private void WebBrowser_LoadFileErrorEvent(ActionResultCollection validationRules){if (validationRules != null && validationRules.HasValidationErrors){this.Dispatcher.Invoke(() =>{var newValudationRules = this.ViewModel.ValidationResults;if (newValudationRules == null){newValudationRules = new ActionResultCollection();}newValudationRules.AddRange(validationRules);this.ViewModel.ValidationResults = newValudationRules;});}}

相关文章:

.NET 6 WPF 利用CefSharp.Wpf.NETCore显示PDF文件

在WPF程序中&#xff0c;我们可以有多种方式显示PDF文件&#xff0c;但是目前发现的性能最好的是CefSharp.Wpf.NETCore。 CefSharp.Wpf.NETCore是一款开源软件。https://github.com/cefsharp/CefSharp。 它提供了WPF版本和WinForm版本&#xff0c;可根据自己的需要进行安装。…...

Hi3518E官方录像例程源码流程分析(五)

文章目录 Venc理论部分阶段五 开始视频流编码SAMPLE_COMM_VENC_Start()s32Ret SAMPLE_COMM_SYS_GetPicSize(enNorm, enSize, &stPicSize);创造Venc channal 码率控制CBRFIXQPVBRHI_MPI_VENC_CreateChnHI_MPI_VENC_StartRecvPic SAMPLE_COMM_VENC_BindVpss 绑定VPsschn0 到…...

JavaScript性能优化实战(3):内存管理与泄漏防范

JavaScript内存模型与垃圾回收机制解析 JavaScript作为一种高级编程语言,其内存管理过程对开发者而言大部分是透明的,但了解其内存模型和垃圾回收机制对于编写高性能应用至关重要。 JavaScript的内存分配与管理 JavaScript引擎在执行代码时会自动为变量和对象分配内存,主…...

基于自主大型语言模型代理的AIoT智能家居

中文标题&#xff1a;基于自主大型语言模型代理的AIoT智能家居 英文标题&#xff1a;AIoT Smart Home via Autonomous LLM Agents 作者信息 Dmitriy Rivkin, Francois Hogan, Amal Feriani, Abhisek Konar, Adam Sigal, Xue Liu, Gregory Dudek 论文出处 《IEEE Internet o…...

Maven 手动添加 JAR 包到本地仓库笔记

Maven 手动添加 JAR 包到本地仓库笔记 背景 Maven 默认从中央仓库&#xff08;repo1.maven.org&#xff09;自动下载依赖&#xff0c;但在以下场景中可能遇到问题&#xff1a; 网络限制&#xff1a; 国内访问 Maven 中央仓库速度较慢&#xff08;尤其未配置镜像时&#xff09…...

CS 系列 USB3.0 工业面阵相机不同快门类型的作用及其区别

关于 CS 系列 USB3.0 工业面阵相机 中不同快门类型的作用及其区别的详细分析&#xff1a; 1. 快门类型概述 工业面阵相机的快门类型主要分为 机械快门、电子快门&#xff08;包括全局快门和滚动快门&#xff09;和 电子前帘快门&#xff0c;但机械快门在工业相机中较少见&…...

【官方正版,永久免费】Adobe Camera Raw 17.2 win/Mac版本 配合Adobe22-25系列软

Adobe Camera Raw 2025 年 2 月版&#xff08;版本 17.2&#xff09;。目前为止最新版新版已经更新2个月了&#xff0c;我看论坛之前分享的还是2024版&#xff0c;遂将新版分享给各位。 Adobe Camera Raw&#xff0c;支持Photoshop&#xff0c;lightroom等Adobe系列软件&#…...

怎么减少tcp 的time_wait时间

减少 TCP 连接的 TIME_WAIT 状态时间是运维中常见的优化问题&#xff0c;尤其是在高并发和大量短连接的场景下&#xff0c;过多的 TIME_WAIT 会占用系统资源&#xff0c;影响系统性能。下面是一些常见的优化方法和措施。 &#x1f539; 1. 修改 TCP 参数 ✅ 调整 tcp_fin_time…...

RK3568平台开发系列讲解(调试篇)debugfs API接口及案例

更多内容可以加入Linux系统知识库套餐(教程+视频+答疑) 🚀返回专栏总目录 文章目录 一、Debugfs API1.1、创建目录和文件1.2、导出数字1.3、绑定一个 size_t 类型的变量1.4、绑定一个 u32 类型的变量1.5、绑定一块二进制数据1.6、绑定到一堆寄存器集合1.7、修改 debugfs…...

文件【Linux操作系统】

文章目录 文件前置知识访问文件之前&#xff0c;为什么文件必须打开&#xff1f;文件的管理 标准流标准错误流的作用是什么&#xff1f; 进程和文件的关系在用户层面文件描述符是访问文件的唯一方式&#xff0c;因为系统调用接口只能通过文件描述符来找到对应的文件 操作文件的…...

PVT曲线:预测高分子材料收缩与翘曲的“热力学密码”

在高分子材料的广阔领域中&#xff0c;PVT 曲线作为一种关键的研究工具&#xff0c;正逐渐展现出其不可忽视的重要性。PVT 曲线&#xff0c;即聚合物材料的压力&#xff08;Pressure&#xff09;、体积&#xff08;Volume&#xff09;和温度&#xff08;Temperature&#xff09…...

IDEA中Quarkus框架(3.13版本)容器编排、压测与调优、注意事项等

Quarkus框架学习的第一部分&#xff0c;请访问&#xff1a; IDEA中Quarkus框架(3.13版本)开发、调试、部署、打包等 五、docker-compose容器编排 1、创建编排文件 cd quarkus-helloworldvi docker-compose.ymldocker-compose.yml内容如下&#xff1a; # yaml 配置实例 ver…...

vue+django+LSTM微博舆情分析系统 | 深度学习 | 食品安全分析

文章结尾部分有CSDN官方提供的学长 联系方式名片 文章结尾部分有CSDN官方提供的学长 联系方式名片 关注B站&#xff0c;有好处&#xff01; 编号&#xff1a; D031 LSTM 架构&#xff1a;vuedjangoLSTMMySQL 功能&#xff1a; 微博信息爬取、情感分析、基于负面消极内容舆情分析…...

CSS初识

CSS能够对⽹⻚中元素位置的排版进⾏像素级精确控制,实现美化⻚⾯的效果.能够做到⻚⾯的样式和结构分离。 可以理解给页面化妆&#xff0c;美化排版。 基本语法规范 选择器{⼀条/N条声明} 选择器决定针对谁修改(找谁) 声明决定修改啥(⼲啥) 声明的属性是键值对&#xff0c…...

Kafka 主题设计与数据接入机制

一、前言&#xff1a;万物皆流&#xff0c;Kafka 是入口 在构建实时数仓时&#xff0c;Kafka 既是 数据流动的起点&#xff0c;也是后续流处理系统&#xff08;如 Flink&#xff09;赖以为生的数据源。 但“消息进来了” ≠ “你就能处理好了”——不合理的 Topic 设计、接入方…...

文件系统常见函数

write系统调用 #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 参数说明 fd 文件描述符&#xff0c;指向已打开的文件或设备&#xff08;如标准输出 1、文件句柄等 buf 指向待写入数据的缓冲区指针&#xff0c;支持任意数据类型&#xf…...

深入理解 G1 GC:已记忆集合(RSet)与收集集合(CSet)详解

已记忆集合&#xff08;RSet&#xff09;与收集集合&#xff08;CSet&#xff09;详解 深入理解 G1 GC&#xff1a;已记忆集合&#xff08;RSet&#xff09;与收集集合&#xff08;CSet&#xff09;详解一、 引言&#xff1a;G1 GC 的基石二、 已记忆集合 (RSet)&#xff1a;跟…...

Android Cordova 开发 - Cordova 解读初始化项目(index.html meta、Cordova.js、config.xml)

一、index.html meta 1、Content-Security-Policy &#xff08;1&#xff09;基本介绍 <meta http-equiv"Content-Security-Policy" content"default-src self data: https://ssl.gstatic.com unsafe-eval; style-src self unsafe-inline; media-src *; i…...

uv run 都做了什么?

uv run 都做了什么&#xff1f; uv run <命令> [参数...] 的主要作用是&#xff1a;在一个由 uv 管理或发现的 Python 虚拟环境中&#xff0c;执行你指定的 <命令>。它会临时配置一个子进程的环境&#xff0c;使其表现得如同该虚拟环境已经被激活一样。这意味着&am…...

Maven 依赖坐标与BOM统一管理

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

UV: Python包和项目管理器(从入门到不放弃教程)

目录 UV: Python包和项目管理器&#xff08;从入门到不放弃教程&#xff09;1. 为什么用uv&#xff0c;而不是conda或者pip2. 安装uv&#xff08;Windows&#xff09;2.1 powershell下载2.2 winget下载2.3 直接下载安装包 3. uv教程3.1 创建虚拟环境 (uv venv) 4. uvx5. 此pip非…...

32单片机——GPIO的工作模式

1、GPIO GPIO&#xff08;General Purpose Input Output&#xff0c;通用输入输出端口&#xff09;是控制或者采集外部器件的信息的外设&#xff0c;即负责输入输出。它按组分配&#xff0c;每组16个IO口&#xff0c;组数视芯片而定。STM32F103ZET6芯片是144脚的芯片&#xff0…...

Science Robotics 新型层级化架构实现250个机器人智能组队,“单点故障”系统仍可稳定运行

近期&#xff0c;比利时布鲁塞尔自由大学博士生朱炜煦与所在团队提出了一种创新的机器人群体架构——“自组织神经系统”&#xff08;SoNS&#xff0c;Self-organizing Nervous System&#xff09;。 它通过模仿自然界中的生物神经系统的组织原理&#xff0c;为机器人群体建立了…...

【HFP】蓝牙HFP协议来电处理机制解析

目录 一、协议概述与技术背景 1.1 HFP协议演进 1.2 核心角色定义 1.3 关键技术指标 二、来电接入的核心交互流程 2.1 基础流程概述&#xff1a;AG 的 RING 通知机制 2.2 HF 的响应&#xff1a;本地提醒与信令交互 三、带内铃声&#xff08;In-Band Ring Tone&#xff0…...

03-谷粒商城笔记

一个插件的install和生命周期的报错是不一样的 Maven找不到ojdbc6和sqljdbc4依赖包 这时候我找到了jar包&#xff0c;然后我就先找到一个jar安装到了本地仓库。 在终端上进行命令了&#xff1a; mvn install:install-file -DfileD:\ojdbc6-11.2.0.4.jar -DgroupIdcom.oracle …...

PHP 反序列化CLI 框架类PHPGGC 生成器TPYiiLaravel 等利用

# 反序列化链项目 -PHPGGC&NotSoSecure -NotSoSecure https://github.com/NotSoSecure/SerializedPayloadGenerator 为了利用反序列化漏洞&#xff0c;需要设置不同的工具&#xff0c;如 YSoSerial(Java) 、 YSoSerial.NET 、 PHPGGC 和它的先决条件。 Deserializati…...

LeetCode热题100——283. 移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2: 输入: nums [0] 输出:…...

C++入门小馆: 探寻vector类

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…...

力扣hot100_链表(3)_python版本

一、25. K 个一组翻转链表 1.1、206. 反转链表 py代码 class ListNode:def __init__(self, val0, next node):self.val valself.next next class Solution:def reverseList(self, head):pre Nonecur headwhile cur:next cur.nextcur.next prepre curcur nextreturn p…...

Lua 第9部分 闭包

在 Lua 语言中&#xff0c;函数是严格遵循词法定界的第一类值。 “第一类值”意味着 Lua 语言中的函数与其他常见类型的值&#xff08;例如数值和字符串&#xff09;具有同等权限&#xff1a; 一个程序可以将某个函数保存到变量中&#xff08;全局变量和局部变量均可&a…...

【Linux】冯诺依曼体系结构及操作系统架构图的具体剖析

目录 一、冯诺依曼体系结构 1、结构图 2、结构图介绍&#xff1a; 3、冯诺依曼体系的数据流动介绍 4、为什么在该体系结构中要存在内存&#xff1f; 二、操作系统架构图介绍 1、操作系统架构图 2、解析操作系统架构图 3、为什么要有操作系统&#xff1f; 前些天发现了一…...

解析虚拟机与Docker容器化服务的本质差异及Docker核心价值

解析虚拟机与Docker容器化服务的本质差异及Docker核心价值 1.1 硬件虚拟化与操作系统级虚拟化 虚拟机&#xff08;VM&#xff09;基于硬件级虚拟化技术&#xff08;Hypervisor&#xff09;&#xff0c;通过模拟完整硬件栈&#xff08;CPU、内存、存储、网络&#xff09;创建独…...

FreeRTOS深度解析:队列集(Queue Sets)的原理与应用

FreeRTOS深度解析&#xff1a;队列集&#xff08;Queue Sets&#xff09;的原理与应用 什么是队列集&#xff1f; 在FreeRTOS中&#xff0c;队列集&#xff08;Queue Sets&#xff0c;英文名xQueueSet&#xff09;是一种强大的数据结构&#xff0c;用于高效管理多个队列。它的…...

java将pdf转换成word

1、jar包准备 在项目中新增lib目录&#xff0c;并将如下两个文件放入lib目录下 aspose-words-15.8.0-jdk16.jar aspose-pdf-22.9.jar 2、pom.xml配置 <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId><versi…...

网络原理 - 6

目录 4. 滑动窗口 滑动窗口出现丢包 情况一&#xff1a;数据报已经抵达&#xff0c;ACK 被丢了​编辑 情况二&#xff1a;数据报直接就丢了 5. 流量控制 完&#xff01; 4. 滑动窗口 这个滑动窗口是 TCP 中非常有特点的机制。 我们知道&#xff0c;TCP 是通过确认应答&…...

【Linux网络】构建类似XShell功能的TCP服务器

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

Spring AI - Redis缓存对话

先看效果 对话过程被缓存到了Redis 中。 原理 在上一节我们快速入门了SpringAI&#xff0c;具体文章请查看&#xff1a;快速入门Spring AI 创建 ChatClient 的代码如下&#xff1a; this.chatClient ChatClient.builder(chatModel).defaultSystem(DEFAULT_PROMPT).defaultAd…...

rk3588 驱动开发(二)第四章嵌入式 Linux LED 驱动开发实验

4.1 Linux 下 LED 灯驱动原理 Linux 下的任何外设驱动&#xff0c;最终都是要配置相应的硬件寄存器。所以本章的 LED 灯驱动 最终也是对 RK3588 的 IO 口进行配置&#xff0c;与裸机实验不同的是&#xff0c;在 Linux 下编写驱动要符合 Linux 的驱动框架。开发板上的 LED 连接…...

第49讲:AI驱动的农业碳汇估算与生态价值评估 —— 打造更“绿”的智慧农业未来

目录 🌍 一、农业碳汇:我们为什么要关心它? 🤖 二、AI是如何介入农业碳汇评估的? 🛠 三、案例实战:AI估算区域农田碳汇储量 📍 场景设定: 📊 数据来源: 🔁 处理流程: 📈 四、生态价值评估:从碳储量到生态效益 🧭 五、平台与工具推荐 💬 六、…...

springmvc入门案例

目录 前言 springmvc概述 springmvc入门案例&#xff08;使用配置类替代原本的web.xml) 第一步、创建一个web工程 第二步、引入相应的依赖&#xff08;servlet-api、spring-webmvc、&#xff09; 第三步、编写 SpringMVC配置类&#xff0c;并开启包扫描功能 第四步、编写…...

Node.js学习

概述 Node.js 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境&#xff0c;允许在服务器端运行 JavaScript 代码。它采用事件驱动和非阻塞 I/O 模型&#xff0c;适合构建高性能、可扩展的网络应用&#xff0c;尤其擅长处理实时应用和大规模数据密集型场景 背景 JavaScri…...

SQL注入漏洞中会使用到的函数

目录 一、信息获取函数 1. 通用函数 2. 元数据查询&#xff08;INFORMATION_SCHEMA&#xff09; 二、字符串操作函数 1. 字符串连接 2. 字符串截取 3. 编码/解码 三、报错注入专用函数 1. MySQL 2. SQL Server 3. PostgreSQL 四、时间盲注函数 1. 通用延迟 2. 计…...

MIT IDSS深度解析:跨学科融合与系统科学实践

麻省理工学院的IDSS(Institute for Data, Systems, and Society, IDSS)是一个致力于通过先进分析方法推动教育与研究的前沿机构。它将工程学、信息科学和数据科学的方法与社会科学的分析方法相结合,以应对复杂的社会挑战。 MIT IDSS 建立在统计学、计算机科学和特定应用领域…...

重塑智慧出行新生态,德赛西威全新战略愿景发布

4月22日&#xff0c;上海车展开幕前夕&#xff0c;德赛西威以“智新境&#xff0c;向远大”为主题&#xff0c;正式对外发布全新发展战略及使命、愿景&#xff1b;同时&#xff0c;代表未来AI出行趋势的智慧出行解决方案Smart Solution 3.0重磅亮相。 一、把握变革节点 创领产…...

全面解析 classification_report:评估分类模型性能的利器

解读 classification_report 的使用&#xff1a;评估分类模型性能的关键工具 在机器学习中&#xff0c;分类任务是最常见的应用场景之一。无论是垃圾邮件过滤、图像识别还是情感分析&#xff0c;分类模型的性能评估都是至关重要的一步。而 classification_report 是 Scikit-le…...

Qt案例 使用QFtpServerLib开源库实现Qt软件搭建FTP服务器,使用QFTP模块访问FTP服务器

本以为搭建和访问FTP服务器的功能已经是被淘汰的技术了&#xff0c;只会在学习新技术的时候才会了解学习学习&#xff0c;WinFrom版本&#xff0c;和windows Api版本访问FTP服务器的功能示例也都写过。没想到这次会在项目中再次遇到&#xff0c; 这里记录下使用Qt开源库QFtpSer…...

图像后处理记录

图像后处理记录 ocr后处理记录 opencv裁剪 编译命令 cmake -S . -B build-x64 -DBUILD_LIST"core,imgproc,imgcodecs,highgui" -DBUILD_SHARED_LIBSOFF -DBUILD_opencv_appsOFF -DBUILD_opencv_jsOFF -DBUILD_ANDROID_PROJECTSOFF -DBUILD_ANDROID_EXAMPLESOFF -…...

解决element中的el-anchor链接被作为路由跳转导致页面404

解决element中的el-anchor链接被作为路由跳转导致页面404 问题&#xff1a; 在使用elementPlus时&#xff0c;el-anchor-link中的href被识别为路由进行跳转&#xff0c;导致不能正常跳转到锚点&#xff0c;且页面显示404。 解决&#xff1a;自定义方法解决 <!--添加hand…...

Mapreduce中maven打包

MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff08;例如&#xff1a;jar包&#xff09;&#xff0c;并发运行在…...

C++初阶——string的使用(下)

C初阶——string的使用&#xff08;下&#xff09; 一、string类对象的容量操作 对于string的容量操作&#xff0c;我们可以通过顺序表来理解&#xff0c;顺序表是通过动态数组来实现的&#xff0c;在数据结构专栏的第一篇就是顺序表的详细讲解&#xff0c;链接如下&#xff…...