Also habe ich die folgende Klasse ...Spiel Art der Steuerung mit der Basisklasse
public partial class CommandBar : UserControl { .. }
..., die ich wie so in der ASCX-Datei enthalten ...
<%@ Register Src="~/.../CommandBar.ascx" TagName="CommandBar" TagPrefix="uc1" %>
...
<uc1:CommandBar ID="CommandBarTop" runat="server" ... />
Meine Ziel im Moment ist es, eine generische Methode zu erstellen, die es einem Benutzer ermöglicht, alle Steuerelemente rekursiv nur lesend zu setzen. Die Methode sollte einen optionalen Parameter bereitstellen, um eine List<Type>
zu ignorierende Steuerelemente anzugeben. In dieser Liste möchte ich diese CommandBar mit typeof(CommandBar)
übergeben, um diese zu ignorieren.
Alles funktioniert wie erwartet, aber ich habe ein wenig Mühe herauszufinden, die richtige Art, diese Typen zu entsprechen.
Betrachten Sie Folgendes;
Object o; // control to check, in this case the `CommandBarTop` object
Type t; // type to ignore
ich erwartet hatte es so so einfach zu sein:
if (o is t){
// ignore
}
... aber ich bekomme eine Syntax Ausnahme „Ein konstanter Wert wird erwartet“. Also habe ich es mit der folgenden Einrichtung versucht:
Es kompilierte, aber nicht wie erwartet funktioniert. Das Problem scheint ein Typ-Fehltreffer zu sein. Wirft man einen Blick auf den Debugger bekomme ich folgendes:
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
ist eigentlich vom Typ t
aber vor allem ist es nicht zugänglich und zweite sollte die Methode generisch sein, einen Basistyp Überprüfung nicht immer wahrscheinlich passen Mach was ich will.
Ich nehme an, dass ASP.NET einen Steuerelementwrapper zur Laufzeit generiert, der dann an den Benutzer gesendet wird. Diese Annahme basiert auf der Assembly-Codebasis, die ich im Debugger sehe. Es sagt der folgende:
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
Ich habe auch versucht, den Typ GUID passende aber da sie im Grunde nicht vom gleichen Typ sind, die entweder nicht funktioniert.
EDIT 1
Ich dachte, es könnte helfen, wenn ich Ihnen meine Methode zeigen die Kontrollen einzustellen rekursiv
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));
}
kommend auf meine Frage jetzt zu Nur-Lesen; Hat jemand eine Idee, wie man dieses Problem lösen kann?
Vielen Dank im Voraus!
Was meinen Sie, wenn Sie über Komponenten sprechen? Vielleicht "Controls" (TextBox, Label ...)? Können Sie einige Beispiele hinzufügen? – Emanuele
@Emanuele jawohl, ich meine Kontrollen. Ich habe meine Frage entsprechend aktualisiert. die Beispiele, die Sie mit TextBox, Label usw. gegeben haben. ist genau was ich meine. Ofc gibt es auch Panels, Tabellen, DropDownLists, .. welche manchmal eine Eigenschaft namens "Controls", "Rows" oder "Cells" selbst haben, deshalb implementiere ich es rekursiv, um zu allen Controls innerhalb der Seite –