Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
6 / 6 / 0
Регистрация: 21.05.2016
Сообщений: 17
WPF

Замена элемента Cef ChromiumWebBrowser на форме

31.07.2021, 14:19. Показов 2881. Ответов 9

Студворк — интернет-сервис помощи студентам
Здравствуйте. Есть форма на которой отображается браузер Cef
XML
1
2
3
4
        
        <DockPanel x:Name="Panel" Grid.Row="1">
                <Cef:ChromiumWebBrowser x:Name="BrowserControl" />
        </DockPanel>
Мне необходимо менять его по требованию, проблема в том, что если делать так:
C#
1
BrowserControl = new ChromiumWebBrowser("google.com");
Ничего не отобразится. Работает только костыльный вариант:
C#
1
2
3
            BrowserFirst ??= new ChromiumWebBrowser();
            Panel.Children.Clear();
            Panel.Children.Add(BrowserFirst);
Это работает, но подозреваю что есть более грамотное решение, так же при таком подходе придется в cb биндить остальные элементы формы, например текстбокс адресной строки и тд к новому элементу. В идеале конечно реализовать с mvvm.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.07.2021, 14:19
Ответы с готовыми решениями:

Некорректное отображение на форме ChromiumWebBrowser
Прошу помощи знатоков! Пишу программу парсинга ВК. При загрузке стартовой формы должно отображаться окно авторизации. На рабочем компьютере...

CefSharp ChromiumWebBrowser Navigating event
Какое событие нужно перехватить в ChromiumWebBrowser, чтобы можно было отменить загрузку страницы? В стандартном WebBrowser это делалось...

CEF 3: процессы и потоки
Добрый день всем! Интро. Была написана у меня программа, использующая cef1. Работа программы заключалась в автоматизации браузера. ...

9
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
31.07.2021, 18:15
c0d3r, очень непонятно объяснили.
Пишите BrowserControl =.../ А что это за элемент BrowserControl?
Так же и дальше. Что за поле BrowserFirst ?
new ChromiumWebBrowser("google.com"), но у ChromiumWebBrowser вроде нет конструктора с параметром.
Дальше вы создаёте новый экземпляр new ChromiumWebBrowser() и он вроде работает.
Но где ссылка на "google.com"?
0
6 / 6 / 0
Регистрация: 21.05.2016
Сообщений: 17
01.08.2021, 09:15  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А что это за элемент BrowserControl?
Он указан в XAML.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Что за поле BrowserFirst ?
BrowserFirst это ChromiumWebDriver. И у него два конструктора.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Дальше вы создаёте новый экземпляр new ChromiumWebBrowser() и он вроде работает.
Судя по всему он работает только из-за того что я удаляю BrowserControl из дочерних элементов докпанели и помещаю туда свой. Указывать в конструкторе ссылку или нет, разницы я не заметил.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
01.08.2021, 10:59
Цитата Сообщение от c0d3r Посмотреть сообщение
BrowserFirst это ChromiumWebDriver. И у него два конструктора.
ChromiumWebDriver или ChromiumWebBrowser ?

У ChromiumWebBrowser, вроде, только один конструктор: https://cefsharp.github.io/api... __ctor.htm.

Цитата Сообщение от c0d3r Посмотреть сообщение
Он указан в XAML.
Не углядел первый раз.
Невнимательность.

Цитата Сообщение от c0d3r Посмотреть сообщение
Мне необходимо менять его по требованию, проблема в том, что если делать так:
BrowserControl - это ПОЛЕ в котором есть ссылка на элемент ChromiumWebBrowser, объявленный в XAML.
Присваивая этому полю, ссылку на другой элемент, вы не помещаете его в визуальное дерево для отображения.

Вам не нужно ЗАМЕНЯТЬ один элемент другим.
Вам надо, что бы этот элемент ЗАГРУЗИЛ другую страницу.

Судя по документации, это можно сделать так:
C#
1
BrowserControl.LoadString("google.com");
Кроме этого метода, есть ещё свойство Address и метод Load(URL).

Цитата Сообщение от c0d3r Посмотреть сообщение
В идеале конечно реализовать с mvvm.
Скорее всего должна работать привязка в свойстве Address:
XML
1
2
3
4
        <DockPanel x:Name="Panel" Grid.Row="1">
                <Cef:ChromiumWebBrowser x:Name="BrowserControl" 
                        Address="{Binding AddressInViewModel}"/>
        </DockPanel>
Но обратите внимание, что Address принимает тип URL.
Binding может автоматически преобразовать строку в URL, но не всегда.
Если строка не корректна, то, наверное, лучше добавить какую-то обработку ошибки, что бы понимать, что это не пустая страница, а некорректная строка.
0
6 / 6 / 0
Регистрация: 21.05.2016
Сообщений: 17
01.08.2021, 11:13  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
ChromiumWebDriver или ChromiumWebBrowser ?
Опечатался, конечно Browser.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
У ChromiumWebBrowser, вроде, только один конструктор: https://cefsharp.github.io/api... __ctor.htm.
В доке 57 версия, у меня 91, скрин во вложении.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
BrowserControl - это ПОЛЕ в котором есть ссылка на элемент ChromiumWebBrowser, объявленный в XAML.
Присваивая этому полю, ссылку на другой элемент, вы не помещаете его в визуальное дерево для отображения.
Вам не нужно ЗАМЕНЯТЬ один элемент другим.
Вам надо, что бы этот элемент ЗАГРУЗИЛ другую страницу.
Мне как раз нужно заменять, потому что на каждом экземпляре Browser будет своя папка данных User Data, и на каждый будут вешать свои хендлеры для выполнения разных Js скриптов. Мне не подходит открытие страниц в одном браузере.
Если бы нужно было открывать в одном браузере разные ссылки, я бы не парился и привязал бы к свойствам вм.
Миниатюры
Замена элемента Cef ChromiumWebBrowser на форме  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
01.08.2021, 11:57
Цитата Сообщение от c0d3r Посмотреть сообщение
Мне как раз нужно заменять, потому что на каждом экземпляре Browser будет своя папка данных User Data....
Это очень не типично для WPF.
И по сути нарушает саму концепцию WPF.
ChromiumWebBrowser - это UI элемент.
И недолжно быть такого, что для изменения представляемых им данных, нужно удалять элемент и создавать новый экземпляр.

Цитата Сообщение от c0d3r Посмотреть сообщение
В доке 57 версия, у меня 91, скрин во вложении.
По конструктору с параметром стринг написано, что фактически это равносильно вызову метода LoadString.
И с большой вероятностью тоже самое можно сделать привязкой в свойстве Address.

Цитата Сообщение от c0d3r Посмотреть сообщение
на каждом экземпляре Browser будет своя папка данных User Data
Вот этого, вооще, не понял.
Как вы задаёте экземпляру эту папку?
0
6 / 6 / 0
Регистрация: 21.05.2016
Сообщений: 17
01.08.2021, 12:59  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как вы задаёте экземпляру эту папку?
Можно передать CefSettings и указать там DataPath ну и другие настройки. Всего будет 5-6 браузеров, но в зависимости от условий мне нужно отображать только 1 из них.
C#
1
2
3
4
5
var browserFirst = new ChromiumWebBrowser();
//устанавливаем настройки и вешаем хендлеры
var browserSecond = new ChromiumWebBrowser();
//устанавливаем настройки и вешаем хендлеры
//и еще штук 5.
и желательно их как-то отображать на форме, тогда когда это требуется.

Добавлено через 28 минут
В официальном репозитории нашел такой пример:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="CefSharp.Wpf.Example.SpawnBrowsersWindow"
        Title="TestWindow" Height="594" Width="651">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ListBox x:Name="itemList" Margin="10,42,10,10" IsSynchronizedWithCurrentItem="False" SelectionChanged="ListBox_SelectionChanged" />
        <ContentControl x:Name="browserContainer" Content="Browser goes here" Grid.Column="1" Margin="10,42,10,10"/>
        <Button Content="Test" x:Name="btnTest" Height="27" Margin="10,10,10,0" VerticalAlignment="Top" Click="Button_Click"/>
        <Label Content="Speed" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Label x:Name="speedLabel" Content="0" Grid.Column="1" HorizontalAlignment="Left" Margin="300,10,0,0" VerticalAlignment="Top"/>
        <Slider x:Name="speedSlider" Grid.Column="1" HorizontalAlignment="Left" Margin="58,15,0,0" VerticalAlignment="Top" Width="237" Maximum="1" Value="0.01" Minimum="0.01" ValueChanged="speedSlider_ValueChanged"/>
        
    </Grid>
</Window>
Основная строчка для меня тут:
XML
1
<ContentControl x:Name="browserContainer" Content="Browser goes here" Grid.Column="1" Margin="10,42,10,10"/>
CB:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private async void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (browserContainer.Content is ChromiumWebBrowser)
            {
                ChromiumWebBrowser oldBrowser = browserContainer.Content as ChromiumWebBrowser;
                browserContainer.Content = null;
                oldBrowser.Dispose();
            }
            await Task.Delay(10);
 
            ChromiumWebBrowser browser = new ChromiumWebBrowser()
            {
                Address = "http://www.google.com"
            };
            browserContainer.Content = browser;
            //browser.ExecuteScriptAsync("document.body.innerHTML = '';");
        }
Пока не тестил.

Добавлено через 23 минуты
Проверил, все работает как надо. Осталось создать ВьюМодель. Теперь нужно разобраться как из другой ВьюМодели, передавать эти браузеры для отображения. Т.е две формы, в одной выбирается сайт который нужно показать, на другой уже отображается.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
01.08.2021, 13:53
Цитата Сообщение от c0d3r Посмотреть сообщение
Всего будет 5-6 браузеров, но в зависимости от условий мне нужно отображать только 1 из них.
На мой взгляд, это очень не верно.

Пример.
У вас есть несколько файлов с картинками.
Вы создаёте список Image и отображаете один из из этого списка.

Но правильно будет, создать ОДИН Image и менять его Sorce.

То же самое и с браузером.
Если вам не не нужно ОДНОВРЕМЕННО выводить несколько страниц, то и не нужно создавать несколько браузеров.

Цитата Сообщение от c0d3r Посмотреть сообщение
Можно передать CefSettings и указать там DataPath ну и другие настройки
Я не нашёл такого метода у ChromiumWebBrowser.
Но сути это не меняет.
Если вы сначала создаёте экземпляр браузера, а потом задаёте значения его свойствам, вызываете его методы, то тоже самое можно сделать с уже имеющимся экземпляром.
Всё концепция UI элементов для WPF построена на этом.

Добавлено через 5 минут
Цитата Сообщение от c0d3r Посмотреть сообщение
Основная строчка для меня тут:
XML
1
<ContentControl x:Name="browserContainer" Content="Browser goes here" Grid.Column="1" Margin="10,42,10,10"/>
Это избыточно.

Цитата Сообщение от c0d3r Посмотреть сообщение
Проверил, все работает как надо.
Тогда, судя по коду, должно работать и такое:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="CefSharp.Wpf.Example.SpawnBrowsersWindow"
        Title="TestWindow" Height="594" Width="651">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ListBox x:Name="itemList" Margin="10,42,10,10" IsSynchronizedWithCurrentItem="False" SelectionChanged="ListBox_SelectionChanged" />
        <Cef:ChromiumWebBrowser x:Name="BrowserControl" Grid.Column="1" Margin="10,42,10,10"/>
        <Button Content="Test" x:Name="btnTest" Height="27" Margin="10,10,10,0" VerticalAlignment="Top" Click="Button_Click"/>
        <Label Content="Speed" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Label x:Name="speedLabel" Content="0" Grid.Column="1" HorizontalAlignment="Left" Margin="300,10,0,0" VerticalAlignment="Top"/>
        <Slider x:Name="speedSlider" Grid.Column="1" HorizontalAlignment="Left" Margin="58,15,0,0" VerticalAlignment="Top" Width="237" Maximum="1" Value="0.01" Minimum="0.01" ValueChanged="speedSlider_ValueChanged"/>
        
    </Grid>
</Window>
C#
1
2
3
4
        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
             BrowserControl.Address = "http://www.google.com";
        }
Добавлено через 2 минуты
Цитата Сообщение от c0d3r Посмотреть сообщение
Т.е две формы, в одной выбирается сайт который нужно показать, на другой уже отображается.
Если это MVVM, то делается через общую Модель.
Непосредственной передачи между Окнами или ViewModel не должно быить.
1
6 / 6 / 0
Регистрация: 21.05.2016
Сообщений: 17
02.08.2021, 10:47  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если это MVVM, то делается через общую Модель.
Можете показать простой пример?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
02.08.2021, 11:03
Цитата Сообщение от c0d3r Посмотреть сообщение
Можете показать простой пример?
Темы "INPC (INotifyPropertyChanged) и получение данных из Модели" и "Передача данных между Окнами, между VM, Шина Сообщений, Локатор" по ссылке в подписи моего поста.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.08.2021, 11:03
Помогаю со студенческими работами здесь

Массивы - замена элемента, нахождение нового массива и максимального элемента
Если не затруднит, помогите, пожалуйста, написать программу на Паскале. Задание: Дана матрица А(5,5) - заполнить генератором...

Поиск элемента и если находится, то замена существующего элемента на найденный
Есть два элемента: ('.banner') и ('.banner_top.'). ('.banner') находится на странице по умолчанию, а ('.banner_top.') периодически...

Chromium Embedded Framework / cef
Пробовал ли кто в деле?https://bitbucket.org/chromiumembedded/cef/src/master/ Оригинальный текст до перевода

CEF - Chromium Embedded Framework
Как реализовать поддержку CEF через плагин в GTA SA-MP?

CEF (Chrome Embedded Framework)
Добрый день, у меня несколько вопросов по этой штуке: 1. Есть какие-нибудь понятные инструкции по этой вещи? 2. Как это впихнуть в C++...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru