- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
是否可以使用 .NET 3.5/4.0 在 WinForm Web 浏览器中检查 HTML 元素?
可能使用 IHighlightRenderingServices 接口(interface)或 Html Agility Pack?
我希望应用程序像 FireBug 一样运行:
只需将鼠标悬停在要检查的元素上,然后单击它。在 1.7 之前的 Firebug 版本中,这会自动切换到 HTML 面板并在节点 View 中选择适当的元素。
编辑:
哇,我刚看到http://www.selectorgadget.com/这正是我想要做的。它是用 Javascript 编写的,在查看了过去 2 小时的源代码后,我仍然不知道如何将它合并到我的程序中......
据我所知,它使用 DOM 元素的标记化和递归分析来找出 CSS 选择器路径:http://www.selectorgadget.com/stable/lib/dom.js .
编辑:好的!我已将 selectorgadget 加载到我的应用程序中。它允许您选择与 Firebug 完全相同的 HTML 元素!甚至创建 Xpath 查询。
但是,我使用的是 AxWebBrowser,我一直在思考如何让它与 HtmlAgilityPack 一起工作......
private void xpathQuery_Click(object sender, EventArgs e)
{
// Load Browser
HtmlWindow window = axWebBrowser1.Document.Window; // <---- 'object' does not contain a definition for 'Window'
string str = window.Document.Body.OuterHtml;
// Load HTML
HtmlAgilityPack.HtmlDocument HtmlDoc = new HtmlAgilityPack.HtmlDocument();
HtmlDoc.LoadHtml(str);
//Process Xpath Query
HtmlAgilityPack.HtmlNodeCollection Nodes = HtmlDoc.DocumentNode.SelectNodes(xpathText.Text);
//Print in Text box
foreach (HtmlAgilityPack.HtmlNode Node in Nodes)
{
richTextBox1.Text += Node.OuterHtml + "\r\n";
}
}
编辑:我无法让 AxWebBrowser 与 HtmlAgilityPack 一起工作,所以我只是使用 WebClient 类加载 URL,然后使用 HtmlAgilityPack 解析它。
我即将完成 Web Scraper。它的功能类似于 Visual Web Ripper 和所有其他价格超过 1,000 美元的产品。
最佳答案
我以前确实做过。您必须将文档转换为 IExpando
,然后您可以对其进行反射调用以获取成员。我实际上创建了一个 DynamicNode
类,它允许您使用 dynamic 关键字与文档进行交互。
您可能想改用 mshtml COM 对象:Reusing MSHTML
var document = new mshtml.HTMLDocument();
var window = (IExpando)document.parentWindow;
例如这是我的动态节点:
class DynamicNode : DynamicObject, IExpando, IEnumerable
{
private IExpando value;
public DynamicNode(IExpando value)
{
this.value = value;
}
public override bool TryUnaryOperation(UnaryOperationBinder binder, out object result)
{
switch (binder.Operation)
{
case System.Linq.Expressions.ExpressionType.Convert:
case System.Linq.Expressions.ExpressionType.ConvertChecked:
result = this.value;
return true;
}
return base.TryUnaryOperation(binder, out result);
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this.value
.GetMembers(BindingFlags.Instance | BindingFlags.Public)
.Select(m => m.Name)
.Distinct()
.ToArray();
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = this.value;
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.Length == 1)
{
var memberName = indexes[0].ToString();
result = ReflectionHelpers.GetValue(this.value, memberName);
result = DynamicNode.Wrap(result);
return true;
}
return base.TryGetIndex(binder, indexes, out result);
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes.Length == 1)
{
var memberName = indexes[0].ToString();
value = DynamicNode.Unwrap(value);
ReflectionHelpers.SetValue(this.value, memberName, value);
return true;
}
return base.TrySetIndex(binder, indexes, value);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (base.TryGetMember(binder, out result))
return true;
result = ReflectionHelpers.GetValue(this.value, binder.Name);
result = DynamicNode.Wrap(result);
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
ReflectionHelpers.SetValue(this.value, binder.Name, value);
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "New")
{
var constructorArgs = new object[args.Length - 1];
Array.ConstrainedCopy(args, 1, constructorArgs, 0, constructorArgs.Length);
result = ReflectionHelpers.New(this.value, (string)args[0], constructorArgs);
}
else
{
result = ReflectionHelpers.Invoke(this.value, binder.Name, args);
}
result = DynamicNode.Wrap(result);
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
IExpando self = this.value;
object[] constructorArgs = new object[0];
if (args.Length > 0)
{
self = (IExpando)DynamicNode.Unwrap(args[0]);
constructorArgs = new object[args.Length - 1];
Array.ConstrainedCopy(args, 1, constructorArgs, 0, constructorArgs.Length);
}
result = ReflectionHelpers.Call(this.value, self, constructorArgs);
result = DynamicNode.Wrap(result);
return true;
}
private static object Wrap(object value)
{
if (value != null && Marshal.IsComObject(value))
value = new DynamicNode((IExpando)value);
return value;
}
public static object Unwrap(object value)
{
DynamicNode node = value as DynamicNode;
if (node != null)
return node.value;
return value;
}
public IEnumerator GetEnumerator()
{
var members = this.value.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var indexProperties = new List<Tuple<int, PropertyInfo>>();
var isArray = true;
foreach (var member in members)
{
int value = 0;
if (!int.TryParse(member.Name, out value))
{
isArray = false;
break;
}
var propertyMember = member as PropertyInfo;
if (propertyMember != null)
indexProperties.Add(Tuple.Create(value, propertyMember));
}
if (isArray)
{
indexProperties.Sort((left, right) => left.Item1.CompareTo(right.Item1));
foreach (var prop in indexProperties)
yield return prop.Item2.GetValue(this.value, null);
}
else
{
foreach (var member in members)
yield return member.Name;
}
}
#region IExpando
FieldInfo IExpando.AddField(string name)
{
return this.value.AddField(name);
}
MethodInfo IExpando.AddMethod(string name, Delegate method)
{
return this.value.AddMethod(name, method);
}
PropertyInfo IExpando.AddProperty(string name)
{
return this.value.AddProperty(name);
}
void IExpando.RemoveMember(MemberInfo m)
{
this.value.RemoveMember(m);
}
FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
{
return this.value.GetField(name, bindingAttr);
}
FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
{
return this.value.GetFields(bindingAttr);
}
MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
{
return this.value.GetMember(name, bindingAttr);
}
MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
{
return this.value.GetMembers(bindingAttr);
}
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
{
return this.value.GetMethod(name, bindingAttr);
}
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
return this.value.GetMethod(name, bindingAttr, binder, types, modifiers);
}
MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
{
return this.value.GetMethods(bindingAttr);
}
PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
{
return this.value.GetProperties(bindingAttr);
}
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
{
return this.value.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
}
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
{
return this.value.GetProperty(name, bindingAttr);
}
object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
{
return this.value.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
Type IReflect.UnderlyingSystemType
{
get { return this.value.UnderlyingSystemType; }
}
#endregion
}
[ComVisible(true)]
public class ScriptObject : IReflect, IExpando
{
private readonly Type type;
private dynamic _constructor;
private dynamic _prototype;
public ScriptObject()
{
type = this.GetType();
}
[DispId(0)]
protected virtual object Invoke(object[] args)
{
return "ClrObject";
}
public dynamic constructor
{
get { return _constructor; }
set { this._constructor = value; }
}
public dynamic prototype
{
get { return _prototype; }
set { this._prototype = value; }
}
public string toString()
{
return "ClrObject";
}
#region IReflect Members
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
return type.GetMethod(name, bindingAttr, binder, types, modifiers);
}
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
{
return type.GetMethod(name, bindingAttr);
}
protected virtual MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
return type.GetMethods(bindingAttr);
}
MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
{
return GetMethods(bindingAttr);
}
FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
{
return type.GetField(name, bindingAttr);
}
FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
{
return new FieldInfo[0]; // type.GetFields(bindingAttr);
}
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
{
return type.GetProperty(name, bindingAttr);
}
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
{
return type.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
}
protected virtual PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
return type.GetProperties(bindingAttr);
}
PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
{
return GetProperties(bindingAttr);
}
MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
{
return type.GetMember(name, bindingAttr);
}
MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
{
return type.GetMembers(bindingAttr);
}
protected virtual object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
{
if (name == "[DISPID=0]")
{
return this.Invoke(args);
}
return type.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
{
return this.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
Type IReflect.UnderlyingSystemType
{
get { return type.UnderlyingSystemType; }
}
#endregion
#region IExpando Members
public FieldInfo AddField(string name)
{
throw new NotImplementedException();
}
public MethodInfo AddMethod(string name, Delegate method)
{
throw new NotImplementedException();
}
public PropertyInfo AddProperty(string name)
{
throw new NotImplementedException();
}
public void RemoveMember(MemberInfo m)
{
throw new NotImplementedException();
}
#endregion
}
public static class ReflectionHelpers
{
private const BindingFlags DefaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
public static object New(this IExpando scope, string functionName, params object[] args)
{
var constructor = (IExpando)scope.GetValue(functionName);
var proto = constructor.GetValue("prototype");
var obj = (IExpando)scope.GetValue("Object");
var instance = (IExpando)obj.Invoke("create", new object[] { proto });
Call(constructor, instance, args);
return instance;
}
public static object Call(this IExpando function, IExpando scope, params object[] args)
{
object[] callArgs = new object[args.Length + 1];
callArgs[0] = scope;
Array.Copy(args, 0, callArgs, 1, args.Length);
return Invoke(function, "call", callArgs);
}
public static void SetValue(this IExpando instance, string propertyName, object value)
{
if (instance == null)
throw new ArgumentNullException("instance");
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentException("Must specify a value.", "propertyName");
Invoke(instance, propertyName, InvokeFlags.DISPATCH_PROPERTYPUT, new object[] { value });
}
public static object GetValue(this IExpando instance, string propertyName)
{
return Invoke(instance, propertyName, InvokeFlags.DISPATCH_PROPERTYGET, new object[0]);
}
public static object Invoke(this IExpando instance, string functionName, object[] args)
{
if (instance == null)
throw new ArgumentNullException("instance");
if (string.IsNullOrEmpty(functionName))
throw new ArgumentException("Must specify a value.", "functionName");
return Invoke(instance, functionName, InvokeFlags.DISPATCH_METHOD, args);
}
private static object Invoke(IExpando instance, string functionName, InvokeFlags flags, object[] args)
{
try
{
args = args.Select(arg => DynamicNode.Unwrap(arg)).ToArray();
switch (flags)
{
case InvokeFlags.DISPATCH_METHOD:
var method = instance.GetMethod(functionName, DefaultFlags);
return method.Invoke(instance, args);
case InvokeFlags.DISPATCH_PROPERTYGET:
var getProp = instance.GetProperty(functionName, DefaultFlags);
return getProp.GetValue(instance, null);
case InvokeFlags.DISPATCH_PROPERTYPUT:
case InvokeFlags.DISPATCH_PROPERTYPUTREF:
var setProp = instance.GetProperty(functionName, DefaultFlags);
if (setProp == null)
setProp = instance.AddProperty(functionName);
setProp.SetValue(instance, args[0], null);
return null;
default:
throw new NotSupportedException();
}
}
catch (COMException comex)
{
switch ((uint)comex.ErrorCode)
{
// Unexpected script error. This will be handled by the IProcess.UnhandledException event
case 0x80020101:
return null;
default:
throw;
}
}
}
private enum InvokeFlags
{
DISPATCH_METHOD = 1,
DISPATCH_PROPERTYGET = 2,
DISPATCH_PROPERTYPUT = 4,
DISPATCH_PROPERTYPUTREF = 8,
}
}
您实际上可以通过这种方式将 .net 对象粘贴到文档中,或者从 .net 中拉出对象并与它们交互。您还可以将 js 作为字符串进行评估,并让它调用 .net 函数。以下是一些使用代码片段:
获取和设置一个js对象的成员:
this.host.Window.eval(@" Foo = { }; ");
var foo = this.host.Window.Foo;
foo.B = 7.11;
Assert.Equal(7.11, foo.B);
从 C# 调用 js 函数:
this.host.eval("function add(x, y) { return x + y; }");
var z = (int)this.host.Window.add(7, 11);
Assert.Equal(7 + 11, z);
将 .net 对象插入文档并从 js 调用其成员:
this.host.Window.Custom2 = new Custom2();
this.host.Window.eval(@"
function test() {
return Custom2.Test().Value;
}");
bool success = this.host.Window.test();
Assert.True(success);
不过,您只能将继承自 ScriptObject 的对象粘贴到文档中(在上面的代码块中定义)。好吧,我认为你可以在里面放任何东西,但如果它们不实现 IReflect,你会得到奇怪的行为。
关于c# - .NET WebBrowser - FireBug 样式检查 HTML 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9502968/
我喜欢调整 目录的样式(例如背景颜色、字体)预订 , Gitbook 风格 HTML 文档。 这可能吗?如果是这样,有人可以善意地指出我可以开始这样做的地方吗? 谢谢你。 最佳答案 两个步骤: 1)
是否可以使用纯 CSS 选择器根据子节点的兄弟节点数量为节点子节点(在我的例子中为 UL)提供不同的属性,特别是高度? 例如,如果一个节点有 1 个子节点,则 UL 的高度是自动的,但是如果该节点有
我正在与 Vala 一起工作,它首先编译为 C,然后正常从 C 编译。 valac 的一项功能(Vala 编译器)是为 .vala 生成“fast-vapi”文件。 fast-vapi 本质上是为 .
我有两个具有 .body 类的 div,但是,一个位于另一个具有 .box 类的 div 中 - 如下所示: 我只想为 .box 内部的 .body 设置样式...但我在下面所
**注意所有 <> 标签已被删除以允许代码显示**我已经玩了好几个小时了,如果不在设计结束时使用解决方法(即 Corel 绘图),我就无法真正让它工作 *在我继续之前, 首先,网站 URL 是 Adv
我从一个服务中接收到一个字符串,该字符串显然使用 UTF-32 编码对其 unicode 字符进行编码,例如:\U0001B000(C 风格的 unicode 编码)。但是,为了在 JSON 中序列化
我在应用程序资源中有一种样式,我想将其应用于许多不同的饼图。样式如下所示: 为了简单起见,我排除了更多的属性。这一切都很好。现在,我的一些馅饼需要有一个不同的“模型
想象一下,我有一个名为“MyCheckBoxStyle”的 CheckBox 自定义样式。 如何制作基于 MyCheckBoxStyle 嵌入自定义 DataGridCheckBoxColumn 样式
我有一个 Button我在 WPF 中开发的样式,如 this question 中所述.我想用这种风格做的另一件事是拥有 Button缩小一点点,使其看起来像被点击一样被点击。现在,转换代码如下所示
我为超链接控件创建了一个样式:
不知道为什么,但我的 typeahead.js 远程自动完成停止工作。我没有更改任何关于 typeahead.js 的代码,但既然它坏了,我一定是错的。你能看看我的site here吗? ?我会创建
有没有办法创建扩展当前样式的样式,即不是特定样式? 我有一个 WPF 应用程序,我在其中创建样式来设置一些属性,例如边框或验证。 现在我想尝试一些主题,看看哪
我正在为一个网站提出问题,并希望 var reltext 中的正确/再试消息具有不同的颜色,即绿色表示正确,红色表示错误,并且每个旁边可能有一个小 png。 有什么想法吗? A local co
我想到达列表的父节点(使用 id 选择器)并使用纯 JavaScript 添加背景颜色来设置其样式。这是我的代码,但不起作用。 var listParentNode; listPare
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 4 年前。 Improve th
过去几天我一直在与这段代码作斗争,我真的不知道该如何处理它。 基本上,当用户将鼠标滚动到主导航菜单中的某个 LI 元素上时,就会运行一个 Javascript 函数,并根据触发该函数的元素将链接放入下
使用这个可爱的 html 和 css 作为指南,我能够在我的照片上显示我的姓名首字母。 这很好,但是,如果图像不存在,我只想显示首字母;如果图像存在,则不应渲染 peron 首字母。 换句话说,当该图
使用这个可爱的 html 和 css 作为指南,我能够在我的照片上显示我的姓名首字母。 这很好,但是,如果图像不存在,我只想显示首字母;如果图像存在,则不应渲染 peron 首字母。 换句话说,当该图
是否有人尝试过将 JButton 设计为看起来像 NetBeans 工具栏按钮?这将只显示一张图片,当您将鼠标悬停在它上面时,会显示 1px 圆形角灰色边框,并且按钮顶部和底部的背景不同......似
在 Ax2012 中使用图表,它们工作正常。但我想更改它在启动时显示的图表类型,例如“样条”图表,而不是默认的“柱状图”图表。 这是我现在拥有的: http://i.stack.imgur.com/R
我是一名优秀的程序员,十分优秀!