Важно помнить, что, хотя Puppeteer отлично справляется с размытием границ между вашим приложением и Chromium, при получении или отправке данных с использованием вызова evaluate
выполняется сериализация / десериализация.
Короче говоря, я считаю, что лучший способ играть с хромом - это попытаться решить все в функции оценки и вернуть все данные , которые вам нужны.
Это выглядит хорошо для меня
const hrefs = await page.$eval( 'a', anchors => anchors.map(a => a.href ));
hrefs.forEach( h => console.log(h)); // prints the href
Теперь, допустим, вы хотите поиграть с элементами HTML. Лучший способ сделать это - использовать функцию $$
const anchors = await page.$('a');
anchors
- это не массив элементов HTML, а массив ElementHandles ]. ElementHandle - это в основном указатель на элемент в Chromium.
Теперь вы можете передать это ElementHandle
в качестве аргумента функции evaluate
.
const promises = anchors.map(h => page.evaluate(h => h.href, h));
var hrefs = await Promise.all(promises);
hrefs.map(p => console.log(p));
Как видите, перемещение элементов между хромом и вашим приложением не так прозрачно, как вы думаете, но это выполнимо.
DependencyPropertyHelper.GetValueSource
предоставит вам ValueSource
, который включает в себя свойство для извлечения BaseValueSource
. Перечисление BaseValueSource
сообщает вам, откуда DependencyProperty
получает свое значение, такое как наследуется от родителя, устанавливается через стиль или устанавливается локально.
Обновлен после дальнейшего копания
Существует метод ReadLocalValue
, который тупо читается вместо того, чтобы его было так трудно обнаружить в intellisense. (Я думаю, что в книге Apress WPF действительно есть примечание об этом.) Она вернет UnsetValue , если значение не было установлено.
if (ReadLocalValue(Control.DataContextProperty) !=
DependencyProperty.UnsetValue)
{
// Data context was set locally.
}
Если вам по какой-то причине нужно получить все локально устанавливаемых свойств, вы можете использовать LocalValueEnumerator.
LocalValueEnumerator enumerator = GetLocalValueEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Current.Property == Control.DataContextProperty)
{
// DataContext was set locally
}
}
И эти два метода действительно меня удивляют. Читайте вместо Get в ReadLocalValue и коллекции, которую вы не можете перебрать с foreach в GetLocalValueEnumerator. Как будто в .Net есть эти замечательные стандартные вещи, которые команда WPF просто решила проигнорировать.