5 Stimmen

Wie aktualisiert man die UserControl-Schnittstelle zur Entwurfszeit basierend auf dem Eigenschaftswert?

Ich habe ein UserControl mit der folgenden öffentlichen Eigenschaft erstellt:

[Browsable(true)]
public string Text
{
    get { return pnlLookupTable.GroupingText; }
    set { pnlLookupTable.GroupingText = value; }
}

pnlLookupTable ist, wie Sie vielleicht schon erraten haben, ein Panel-Steuerelement. Ich kann den Wert der Eigenschaft "Text" im Fenster "Eigenschaften" ändern, und er wird im Markup widergespiegelt, wie es sein sollte. In der Entwurfsansicht des UserControls innerhalb einer Seite wird jedoch kein aktualisierter GroupingText für das Panel angezeigt. Wie kann ich dies bewerkstelligen?

EDIT :

Auf Wunsch finden Sie hier die gesamte Klasse, zu der diese Eigenschaft gehört. Sie können sehen, dass nichts Besonderes vor sich geht:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class LookupTable : System.Web.UI.UserControl
{
    [Browsable(true)]
    public string Text
    {
        get { return pnlLookupTable.GroupingText; }
        set { pnlLookupTable.GroupingText = value; }
    }
}

Und hier ist der relevante Teil der .ascx-Datei:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="LookupTable.ascx.cs" Inherits="LookupTable" %>
<asp:Panel ID="pnlLookupTable" runat="server" GroupingText="Lookup Table">
    <%-- Irrelevant content here. --%>
</asp:Panel>

Ich habe einige Bezeichner und andere triviale Dinge geändert, um den proprietären Charakter des Codes zu schützen.

Ich sollte auch wiederholen, dass ich ein Webformular im Entwurfsmodus betrachte, dem mein Steuerelement hinzugefügt wurde, und ich ändere die Eigenschaft Text. Ich möchte die Änderung des GroupingText des Panels visuell im Designer sehen.

6voto

Eilon Punkte 25347

Ich müsste ein wenig an den UserControlDesigner-Code zurückdenken...

Kurze Geschichte: Ich glaube nicht, dass das möglich ist.

Und das ist die lange Geschichte:

Soweit ich mich erinnere, werden Benutzersteuerelemente, die sich in ASCX-Dateien befinden, niemals im Designer ausgeführt. Das heißt, der Code in der ASCX- oder ASCX.CS-Datei wird nie in Visual Studio kompiliert oder ausgeführt. Damit sollen Speicherlecks vermieden werden, die dadurch entstehen, dass man in der CLR geladene Assemblies nicht entladen kann. Um den Code in Ihrem Benutzersteuerelement auszuführen, müsste Visual Studio Ihre ASCX-Datei in eine DLL kompilieren, sie dann laden und anschließend den Code ausführen. Jedes Mal, wenn Sie eine Änderung am ASCX vornehmen, müsste dieser Vorgang erneut durchgeführt werden. Jedes Mal, wenn dieser Vorgang durchgeführt wird, wird durch die zusätzlich geladene DLL, die aus Ihrem ASCX generiert wurde, mehr Speicher verbraucht.

Aufgrund dieser Einschränkung in der CLR kompiliert der User Control Designer die ASCX-Datei nicht wirklich und führt sie auch nicht aus. Stattdessen analysiert er die ASCX-Datei und sucht darin nach Steuerelementen und lädt diese stattdessen. Für jedes Steuerelement, das er in der ASCX-Datei findet, erstellt er den zugehörigen Steuerelementdesigner und rendert den HTML-Code des Steuerelements zur Entwurfszeit.

Es gibt mehrere Möglichkeiten, dieses Problem zu umgehen:

  1. Anstatt ein ASCX-Benutzersteuerelement zu verwenden, können Sie ein reguläres benutzerdefiniertes Steuerelement schreiben, das von Control abgeleitet ist, und der Code wird in einer CS- oder VB-Datei geschrieben.
  2. Kompilieren Sie das ASCX in eine DLL. David Ebbo schrieb eine Blogbeitrag wie dies zu bewerkstelligen ist.

Der Grund, warum diese beiden Lösungen funktionieren sollten, ist, dass sie beide die Kompilierung des Codes in eine DLL beinhalten. Die Idee ist, dass sich die DLL nicht sehr oft ändert, so dass es für Visual Studio sicher ist, die DLL zu laden, ohne das Risiko, sie jedes Mal neu laden zu müssen, wenn sich die DLL ändert (und Speicher zu verlieren).

1voto

womp Punkte 113535

Ich war mir sicher, dass ich eine Antwort darauf hatte, und habe alles aufgeschrieben, aber irgendetwas hat mich dabei gestört, so dass ich das Ganze ein paar Stunden lang getestet habe.

Es hat sich herausgestellt, dass (wie Eilon sagte), ich glaube nicht, dass du das tun kannst.

ASCX-Steuerungen ignorieren vollständig die DesignerAttribute Sie können also keinen benutzerdefinierten Entwurfszeit-Renderer für sie angeben. Ich dachte: "Gut, ich kann das Panel-Steuerelement subclass und geben Sie einen neuen Designer auf sie, die Eigenschaften aus dem übergeordneten Steuerelement erhalten wird". Aber was ist das? Keine Chance. Wenn Sie im Designer auf das übergeordnete Steuerelement des Panels zugreifen, es wird nicht auf den benutzerdefinierten Benutzerkontrolltyp übertragen . Ich kann sehen, dass es ein UserControl ist, und es kann unmöglich ein anderes UserControl als mein TestUserControl sein, aber die Designerklasse löst eine Ausnahme aus, wenn ich versuche, es zu casten!

Um ehrlich zu sein, das macht mich sprachlos. Es ist im Grunde genau das, was Eilon sagt - es ist eine absichtliche Beschränkung auf Web-Benutzer-Steuerelemente im Design-Modus.

Hier ist ein vager Beitrag von Steven Cheng, in dem er vorschlägt, dass die Unterstützung der Entwurfszeit ein No-Go für Web-Benutzersteuerelemente ist.

Auch wenn ich dabei viel gelernt habe, muss ich leider sagen, dass ich nicht glaube, dass ein .ascx ausreichen wird. Ich bin mir ziemlich sicher, dass selbst das Kompilieren zu einer DLL, wie von Eilon vorgeschlagen, nicht ausreicht. Sie müssen wahrscheinlich die benutzerdefinierte Steuerung Weg zu gehen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X