LoadControl в статической / совместно используемой функции

StackOverflow https://stackoverflow.com/questions/1981293

Вопрос

Кто-нибудь знает, как я могу динамически загружать элемент управления внутри общей / статической функции?Сама функция находится внутри класса mustinherit / abstract.(Это ASP.NET проект на VB) Я хочу сделать что-то вроде этого:
VB:

    Public Shared Function GetWidget(ByVal name As WidgetName) As Control
        Select Case name
            Case WidgetName.Name1
                Return LoadControl("~/Control1.ascx")
            Case WidgetName.Name2
                Return LoadControl("~/Control2.ascx")
            Case WidgetName.Name3
                Return LoadControl("~/Control3.ascx")
        End Select
    End Function

мой C # немного подзабылся, поэтому в нем могут быть некоторые синтаксические ошибки:

Public Static Control GetWidget(WidgetName name)  
{  
    switch (name)  
    {  
        Case WidgetName.Name1:  
            return LoadControl("~/Control1.ascx");  
            break;  
        Case WidgetName.Name2:  
            return LoadControl("~/Control2.ascx");  
            break;  
        Case WidgetName.Name3:  
            return LoadControl("~/Control3.ascx");  
            break;  
    }  
}  

(Где WidgetName - это перечислитель.)

Я получаю сообщение "Невозможно ссылаться на экземпляр-член класса из общего метода или инициализатора общего элемента без явного экземпляра класса". , но я не понимаю эту ошибку.Я понимаю, что это значит, я просто не понимаю, почему вызов LoadControl не рассматривается компилятором как явный экземпляр класса.Что не является явным в использовании LoadControl для создания нового элемента управления из файла?Я попытался создать новый пользовательский элемент управления и инициализировать его, затем установить его на другой элемент управления с помощью LoadControl, но безрезультатно.Я также не хочу делать DirectCast, потому что я пытаюсь поместить это в общий класс mustinheret (абстрактный), который, следовательно, не имеет файла .aspx для записи в <%@ Reference Control="~/SomeControlPath.ascx" %>, таким образом, имя класса недоступно.

То, что я пытаюсь сделать, это написать статическую функцию, которая принимает некоторое значение и возвращает элемент управления, основанный только на местоположении исходного файла этого элемента управления.Конечным результатом является изменяемый пользователем список элементов управления.Они получают столбец элементов управления, которые они свободно добавляют, удаляют или переупорядочивают на основе статического списка доступных дочерних элементов управления, который я указываю.Я не женат на таком подходе;это может быть действительно неправильно не только в одном смысле.

да, я знаю, что статические строки, находящиеся там, пахнут кодом, на самом деле это так не выглядит;это упрощение ради того, чтобы задать вопрос.

Все объяснения на C #, VB или простом английском приветствуются.

Это было полезно?

Решение

Это потому, что LoadControl не может быть возвращен из вашего класса?Не могли бы вы попробовать это вместо этого?..

    Protected Static string GetWidget(WidgetName name)  
    {  
        switch (name)  
        {  
            Case WidgetName.Name1:  
                return "~/Control1.ascx";  
                break;  
            Case WidgetName.Name2:  
                return "~/Control2.ascx";  
                break;  
            Case WidgetName.Name3:  
                return"~/Control3.ascx";  
                break;  
      }  
 } 

и вызовите метод, подобный

... = LoadControl(GetWidget(name));

Я подозреваю, что другой альтернативой является приведение элемента управления

Control c;
...
Case ...
   c = (ControlName)LoadControl("~/Control1/.ascx");
   break;
...
return c;

Однако вызывающему коду все равно нужно будет привести его обратно к своему типу...

Другие советы

На самом деле, вы можете сделать это следующим образом (это работает):

UserControl tmp0 = new UserControl();
Control ctl = tmp0.LoadControl("MyControl.ascx");

LoadControl является методом экземпляра на TemplateControl класс, который Page класс наследуется от, и у вас нет экземпляра Page класс внутри вашего static метод (нет this объект, потому что это статический метод).

Здесь вся хорошая информация, но я удивлен, что никто не использовал ее, чтобы перейти к реальному решению исходного вопроса:

Public Shared Function GetWidget(ByVal name As WidgetName,
                                 ByVal onTemplate As TemplateControl) As Control
    Select Case name
        Case WidgetName.Name1
            Return onTemplate.LoadControl("~/Control1.ascx")
        Case WidgetName.Name2
            Return onTemplate.LoadControl("~/Control2.ascx")
        Case WidgetName.Name3
            Return onTemplate.LoadControl("~/Control3.ascx")
    End Select
End Function

Я протестировал это решение, и оно работает.

Мне это нравится больше, чем решение Rippo, потому что оно избавляет вызывающего от необходимости беспокоиться о деталях LoadControl.И это определенно лучшее решение, если с результирующим элементом управления предстоит проделать больше работы, кроме простого его возврата.

Однако я бы не достиг этого решения без ответа CSharpAtl, потому что я (по глупости) не понимал, что LoadControl - это метод в TemplateControl .Как и на оригинальном плакате, я был очень сбит с толку тем, почему я получал ту же ошибку.Я не мог понять, почему было бы неправильно загружать элемент управления в общий метод, и на самом деле, это нормально, если вы знаете, как вызвать LoadControl в этом контексте!

Брайан

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top