在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 ValueConvert-BooleanToVisibilityConverter
3.4 ValueConvert- EnvironmentConverter
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 Ctor
public App()
{
SetCefSettings();
}
#endregion
private void Application_Exit(object sender, ExitEventArgs e)
{
Cef.Shutdown();
}
#region CefSharp Setting
private void SetCefSettings()
{
#if ANYCPU
//Only required for PlatformTarget of AnyCPU
CefRuntime.SubscribeAnyCpuAssemblyResolver();
#endif
var settings = new CefSettings()
{
//By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist data
CachePath = 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-restart
settings.CefCommandLineArgs.Add("enable-media-stream");
//https://peter.sh/experiments/chromium-command-line-switches/#use-fake-ui-for-media-stream
settings.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 Members
public 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 Methods
private 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;
});
}
}