所以我得到了下面的類...匹配類型
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」本身,這就是爲什麼我實現它遞歸去獲得頁面內的所有控件 –