一:背景 1. 講故事 中秋國慶長假結束,哈哈,在老家拍了很多的短視頻,有興趣的可以上B站觀看:https://space.bilibili.com/409524162 ,今天繼續給大家分享各種奇奇怪怪的.NET生產事故,希望能幫助大家在未來的編程之路上少踩坑。 話不多說,這篇看一個.NET程式集泄 ...
在WinForm/WPF中使用CefSharp混合開發時,通常需要自定義滾動條樣式,以保證應用的整體風格統一。本文將給出一個簡單的示例介紹如何自定義CefSharp中滾動條的樣式。
基本思路
在前端開發中,通過CSS來控制滾動條的樣式是件尋常的事情。CefSharp也提供了功能強大的API方便開發人員使用c#與JS進行交互。這也給我們提供了一個思路:在CefSharp載入完成後,使用其提供的ExecuteJavaScriptAsync
方法註入JS和CSS代碼來自定義滾動條樣式。
實現細節
為了排除干擾以及方便介紹,本文直接從GitHub上下載CefSharp.MinimalExample的示例代碼進行修改。
首先用CSS定義滾動條的樣式,介紹滾動條組成部分以及通過CSS控制其樣式的文章挺多,比如MDN Web Docs。這裡直接貼代碼。
/*定義滾動條高寬及背景 高寬分別對應橫豎滾動條的尺寸*/
::-webkit-scrollbar
{
width: 6px;
height: 6px;
background-color: #FFF;
cursor:pointer;
}
/*定義滾動條軌道 內陰影+圓角 */
::-webkit-scrollbar-track
{
box-shadow: inset 0 0 6px rgba(155,155,155,0.3);
border-radius: 5px;
background-color: #FFF;
cursor:pointer;
}
::-webkit-scrollbar-button
{
display: none;
}
/*定義滑塊 內陰影+圓角*/
::-webkit-scrollbar-thumb
{
border:1px solid #c6c6c6;
border-radius: 5px;
background: #c6c6c6;
cursor:pointer;
background-repeat: no-repeat;
background-position:center;
}
接下來就是把CSS樣式註入到CefSharp中,按照CefSharp的wiki描述,JavaScript腳本只能在V8Context
中執行,並且是在Frame級別執行。對於沒有上下文的在Frame,一旦在Frame載入,就可以使用IFrame.ExecuteJavaScriptAsync
創建V8Context
。
在CefSharp中,IBrowser
和IFrame
對象用於向瀏覽器發送命令和在回調方法中獲取狀態信息,每個IBrowser
對象都有一個主IFrame
對象表示頂層frame(MainFrame),零個或多個IFrame對象表示子frame。
為了儘早把CSS樣式註入到CefSharp中,可以在監聽Browser.FrameLoadEnd
事件並執行腳本。
public MainWindow()
{
InitializeComponent();
Browser.FrameLoadEnd += Browser_FrameLoadEnd;
}
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
//這裡的style就是上一個代碼片段中css樣式的字元串
AddStyle(style);
}
}
/// <summary>
/// 添加CSS樣式表
/// </summary>
/// <param name="style">樣式內容</param>
public void AddStyle(string style)
{
if (string.IsNullOrEmpty(style)) return;
StringBuilder sb = new StringBuilder();
sb.AppendLine("{let script = document.createElement('style');");
sb.Append("let node=document.createTextNode('").Append(style.Replace("\n", string.Empty).Replace("\r", string.Empty)).Append("');");
sb.AppendLine("script.appendChild(node);");
sb.AppendLine("let elements = document.getElementsByTagName('head');");
sb.AppendLine("if(elements.length>0){elements[0].appendChild(script);}");
sb.AppendLine("else if( (elements = document.getElementsByTagName('body')).length>0){elements[0].appendChild(script);}}");
Browser.GetMainFrame().ExecuteJavaScriptAsync(sb.ToString());
}
實現效果如下,滾動條的樣式已被修改。在CefSharp的開發者工具中也可以看到註入的CSS樣式。