Заметил переходы из поисковиков по запросам «geckofx вкладки» и т.п., но такой статьи нет. Будем исправляться 🙂
Итак, в этой статье будет описан пример простенького браузера с поддержкой вкладок.
Исходники в конце статьи.
Почитать о том, как работать с GeckoFX в C# можно здесь.
Для организации поддержки вкладок потребуется компонент TabControl, в каждой вкладке этого компонента будет располагаться компонент GeckoWebBrowser.
Начнем с дизайна 🙂 Свойства формы: Name = FrmMain, WindowState = Maximized, Text = GeckoFx Tabs, Size = 457; 389, StartPosition = CenterScreen. Теперь бросаем на форму:
- MenuStrip, добавляем пункт «Вкладки», пункту «Вкладки» добавляем подпункты «Добавить вкладку» (Name = tsmiAddTab) и «Закрыть активную вкладку» (Name = tsmiCloseActiveTab);
- Label (Name = lblAddress, Location = 0; 24, Text = Адрес:);
- TextBox (Name = tbUrl, Location = 3; 40, Size = 384; 20, Anchor = Top, Left, Right);
- Button (Name = btnGo, Location = 393; 38, Size = 45; 23, Anchor = Top, Right, Text = Go);
- TabControl (Name = tcBrowsersTabs, Location = 3; 66, Size = 435; 286, Anchor = Top, Bottom, Left, Right).
Теперь приступим к написанию кода. Думаю, комментариев, которые присутствуют в коде, достаточно 🙂
Добавим приватное поле:
1 |
private readonly Dictionary<GeckoWebBrowser, TabPage> _wbPages; |
Нужно оно для того, чтобы получить ссылку на вкладку, зная ссылку на контрол браузера и наоборот.
Код конструктора формы заменим на следующий:
1 2 3 4 5 6 7 8 9 10 11 |
public FrmMain() { // инициализация Xulrunner Xpcom.Initialize( Application.StartupPath + "\\xulrunner\\" ); // устанавливаем UserAgent браузера в Firefox 22 GeckoPreferences.User[ "general.useragent.override" ] = "Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20130405 Firefox/22.0"; this.InitializeComponent(); this._wbPages = new Dictionary<GeckoWebBrowser, TabPage>(); this.AddTab(); } |
Т.е. инициализируем движок Gecko, изменяем юзер-агент, создаем экземпляр словаря и вызываем метод добавления вкладки, который приведен ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
private void AddTab( string url = "http://www.google.ru/" ) { TabPage tabPage = new TabPage( "Вкладка №" + ( this.tcBrowsersTabs.TabPages.Count + 1 ) ); var webBrowser = new GeckoWebBrowser { Dock = DockStyle.Fill }; // обработчик события изменения заголовка webBrowser.DocumentTitleChanged += this.webBrowser_DocumentTitleChanged; // обработчик создания окна webBrowser.CreateWindow2 += this.webBrowser_CreateWindow2; // обработчик события завершения загрузки webBrowser.DocumentCompleted += this.webBrowser_DocumentCompleted; // добавляем контрол браузера на новую вкладку tabPage.Controls.Add( webBrowser ); // добавляет новую вкладку this.tcBrowsersTabs.TabPages.Add( tabPage ); // делаем активной новую вкладку this.tcBrowsersTabs.SelectedTab = tabPage; this._wbPages.Add( webBrowser, tabPage ); // загружаем страницу webBrowser.Navigate( url ); } |
Теперь нужно реализовать обработчики событий DocumentTitleChanged, CreateWindow2 и DocumentCompleted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
private void webBrowser_DocumentCompleted( object sender, EventArgs e ) { this.SetCurrentUrl(); } private void webBrowser_CreateWindow2( object sender, GeckoCreateWindow2EventArgs e ) { // запрещаем создавать новые окна e.Cancel = true; var webBrowser = sender as GeckoWebBrowser; if ( webBrowser == null ) { return; } webBrowser.Navigate( e.Uri ); } private void webBrowser_DocumentTitleChanged( object sender, EventArgs e ) { var webBrowser = sender as GeckoWebBrowser; if ( webBrowser == null ) { return; } if ( !this._wbPages.ContainsKey( webBrowser ) ) { return; } // зная ссылку на браузер получаем ссылку на вкладку TabPage tabPage = this._wbPages[ webBrowser ]; // изменяем заголовок вкладки на заголовок страницы tabPage.Text = webBrowser.DocumentTitle; } |
Метод для закрытия вкладки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
private void CloseActiveTab() { // получаем активную вкладку TabPage selectedTab = this.tcBrowsersTabs.SelectedTab; if ( selectedTab == null ) { return; } // получаем ссылку на браузер GeckoWebBrowser webBrowser = this.GetWebBrowserByActiveTab(); // удаляем со словаря this._wbPages.Remove( webBrowser ); // уничтожаем браузер webBrowser.Dispose(); webBrowser = null; // удаляем вкладку this.tcBrowsersTabs.TabPages.Remove( this.tcBrowsersTabs.SelectedTab ); // принудительно запускаем сборщик мусора GC.Collect(); } |
Еще нам понадобится метод, который будет возвращать ссылку на браузер, который находится в активной вкладке:
1 2 3 4 5 6 7 8 |
private GeckoWebBrowser GetWebBrowserByActiveTab() { // получаем активную вкладку TabPage selectedTab = this.tcBrowsersTabs.SelectedTab; // ищем первый элемент в словаре, значения которого (т.е. ссылка на вкладку) равна активной вкладке // данный метод возвратит либо ссылку на браузер, либо null return this._wbPages.FirstOrDefault( t => t.Value == selectedTab ).Key; } |
Метод, который изменяет ссылку в TextBox на текущий URL браузера активной вкладки. Этот метод будет вызываться в момент переключения вкладок и после завершения загрузки страницы:
1 2 3 4 5 6 7 8 9 |
private void SetCurrentUrl() { GeckoWebBrowser webBrowser = this.GetWebBrowserByActiveTab(); if ( webBrowser == null ) { return; } this.tbUrl.Text = webBrowser.Url.ToString(); } |
И, наконец, реализация следующих обработчиков: tsmiAddTab_Click (нажатие на пункт меню «Добавить вкладку»), tsmiCloseActiveTab_Click (нажатие на пункт меню «Закрыть активную вкладку»), btnGo_Click (нажатие на кнопку «Go»), tcBrowsersTabs_SelectedIndexChanged (изменения индекса активной вкладки, т.к. когда пользователь переключается на другую вкладку):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
private void tsmiAddTab_Click( object sender, EventArgs e ) { this.AddTab(); } private void tsmiCloseActiveTab_Click( object sender, EventArgs e ) { this.CloseActiveTab(); } private void btnGo_Click( object sender, EventArgs e ) { GeckoWebBrowser webBrowser = this.GetWebBrowserByActiveTab(); if ( webBrowser == null ) { return; } // открываем указанную ссылку webBrowser.Navigate( this.tbUrl.Text ); } private void tcBrowsersTabs_SelectedIndexChanged( object sender, EventArgs e ) { this.SetCurrentUrl(); } |
Должно получиться что-то типа такого:
На этом всё 🙂 Спасибо за внимание.
Вопросы можно задать в комментариях.
Все супер!!! Вот только как сделать авторизацию Proxy по логину и паролю?
Невыводится на экран, окно авторизация Basic!
У версиях gecko 10 — работает все нормально а вот с версий 22 и выше окно авторизации прокси не выводится(
Автоматически авторизироватся не получается(
Помогите решить проблему. Спасибо..
На счет прокси — хз, нужно будет ковырнуть.
П.С. Что-то ваш комментарий посчитали спамом, потому так долго ответа не было.
Только что проверил — окно авторизации выводиться без проблем.
Здравствуйте еще рас, спасибо за ответ. А можно узнать как Вы настроились на прокси? У меня так и нечего не получилось! В ранних версиях все работает. В новых окно не выскакивает(
Свяжитесь со мной пожалуйста по почте, для обмена новых идей программирования). Спасибо..
Вот так:
var proxy = new Uri( "http://localhost:8080" );
GeckoPreferences.User[ "network.proxy.http" ] = proxy.Host;
GeckoPreferences.User[ "network.proxy.http_port" ] = proxy.Port;
GeckoPreferences.User[ "network.proxy.ssl" ] = proxy.Host;
GeckoPreferences.User[ "network.proxy.ssl_port" ] = proxy.Port;
GeckoPreferences.User[ "network.proxy.type" ] = 1;
На мыло отправил исходник.
P.S. Т.к. не нашел бесплатных прокси с логином и паролем, то подымал локальный с помощью HandyCache.
Да все работает у вашем исходнике, ща буду разбиратся в чем может быть прикол. Спасибо..
Я отправил Вам письмо, прочтите пожалуйста..
Доброе утро. Не подскажите как сделать чтоб при переходе из поисковика добавлялась новая вкладка, а не открывался сайт в тойже вкладке.
Есть событие у браузера «Navigating», вот в нем смотреть и открывать новую вкладку при необходимости.