所以我得到了下面的类...匹配类型
public partial class CommandBar : UserControl { .. }
...我包括像这样的.ascx文件...
<%@ Register Src="~/.../CommandBar.ascx" TagName="CommandBar" TagPrefix="uc1" %>
...
<uc1:CommandBar ID="CommandBarTop" runat="server" ... />
我目前的目标是创建一个通用方法,允许用户将所有控件设置为只读递归。该方法应该提供一个可选参数来指定要忽略的控件的List<Type>
。在这个列表中,我想通过与typeof(CommandBar)
这个CommandBar忽略这些。
一切正常工作,但我有点麻烦找出正确的方式来匹配这些类型。
请考虑以下内容;
Object o; // control to check, in this case the `CommandBarTop` object
Type t; // type to ignore
我希望它是那么容易这样的:
if (o is t){
// ignore
}
...但我得到一个语法异常“的常数值,预计”。所以我试着用下面的设置:
if (t == typeof(o)){
// ignore
}
它确实编译,但没有像预期的那样工作。这个问题似乎是一种类型错配。在调试纵观我得到如下:
t => {Name = "CommandBar" FullName = "My.Name.Space.Controls.CommandBar"} System.Type {System.RuntimeType}
o => {ASP.controls_commandbar_ascx} object {ASP.controls_commandbar_ascx}
o.base
实际上是t
类型,但首先它是不可访问的第二个方法应该是通用的,检查的基本类型匹配可能不会总是做我想做的事。
我假设ASP.NET在运行时生成一个控件包装,然后发送给用户。这个假设是基于我在调试器中看到的汇编代码库。它说以下内容:
t.Assembly.CodeBase => "file:///.../bin/My.Name.Space.Project.DLL" string
o.GetType().Assembly.CodeBase => "file:///C:/Windows/Microsoft.NET/Framework/.../Temporary ASP.NET Files/root/.../App_Web_....DLL" string
我也试过匹配类型GUID,但由于他们基本上不是同一类型,不能正常工作。
编辑1
我想这可能帮助,如果我告诉你我的方法来设置控件为只读递归
public static void SetControlRecursivelyReadOnly(Object control, Boolean readOnly, IEnumerable<Type> controlTypesToIgnore = null)
{
if (null == control)
{
return;
}
new List<KeyValuePair<Type, String>>
{
// define all types which are relevant to access possible child controls
new KeyValuePair<Type, String>(typeof(ControlCollection), "Controls"),
new KeyValuePair<Type, String>(typeof(TableRow), "Rows"),
new KeyValuePair<Type, String>(typeof(TableCell), "Cells")
}.ForEach(x =>
{
// get defined property
Object property = typeof(Reflection).GetMethod("GetProperty")
.MakeGenericMethod(x.Key)
.Invoke(null,
new[]
{
control,
x.Value
});
// check if property is found and is IENumerable
if (!(property is IEnumerable))
{
return; // continues the foreach loop
}
// call recursive
foreach (Object o in (IEnumerable) property)
{
// <--- TODO CHECK IF CONTROL TYPE SHOULD BE IGNORED --->
SetControlRecursivelyReadOnly(o, readOnly);
}
});
// set relevant properties accordingly to readOnly parameter
new List<Tuple<PropertyInfo, Boolean>>
{
new Tuple<PropertyInfo, Boolean>(control.GetType().GetProperty("ReadOnly"), readOnly),
new Tuple<PropertyInfo, Boolean>(control.GetType().GetProperty("EnableButtons"), !readOnly),
new Tuple<PropertyInfo, Boolean>(control.GetType().GetProperty("Enabled"), !readOnly)
}.Where(x => null != x.Item1)
.ToList()
.ForEach(x => x.Item1.SetValue(control, x.Item2, null));
}
来我现在的问题;任何人有一个想法如何解决这个问题?
在此先感谢!
你的意思是,当你谈论组件?也许“控件”(TextBox,Label ...)?你可以添加一些例子吗? – Emanuele
@Emanuele是的,先生,我的意思是控制。我相应地更新了我的问题。你用TextBox,Label aso给出的例子。正是我的意思。 Ofc也有Panels,Tables,DropDownLists,..有时候会有一个属性叫做“Controls”,“Rows”或者“Cells”本身,这就是为什么我实现它递归去获得页面内的所有控件 –