Как включить собственную ссылку на серверный элемент управления в вызов внешнего метода? - PullRequest
1 голос
/ 14 декабря 2010

У меня есть элемент управления Asp.Net TextBox, свойство которого мне нужно оценить, используя отдельный класс (из кода, содержащего страницу). Я хочу это сделать так:

<asp:TextBox ID="myTB" runat="server" Enabled="<% ToggleControl(this, "someBusinessValue") %>" ... />

Причина, по которой мне нужно передать ссылку на вызывающий элемент управления, состоит в том, чтобы выяснить, есть ли другие свойства, которые мне, возможно, нужно будет рассмотреть, прежде чем отключить его. Однако ключевое слово this относится к странице в целом. А так как мой TextBox может быть внутри FormView или GridView, я не могу просто получить контроль, изучив «page.myTB». Я не хочу начинать пахать через GridViews в получающем файле класса только для того, чтобы получить ссылку на TextBox.

Кто-нибудь знает, как ссылаться на встроенный элемент управления таким образом?

РЕДАКТ. 1: Это необходимо сделать для нескольких различных типов серверных элементов управления, таких как ListBox, CheckBox, RadioButtonList и т. Д.

РЕДАКТИРОВАТЬ 2: Лучшее, что я до сих пор придумал, это:

<asp:TextBox ID="myTB" runat="server" Enabled="<% ToggleControl(myGridView.FindControl("myTB") as WebControl, "someBusinessValue") %>"

что не слишком элегантно, но дает мне ту автореференцию, которая мне нужна.

Ответы [ 3 ]

1 голос
/ 14 декабря 2010

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

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

=============================================== ============

Вы никогда не хотите передавать управление любому другому объекту. Причина в том, что если вам нужно изменить пользовательский интерфейс приложения, вам придется перестраивать все, что имеет отношение к этому элементу пользовательского интерфейса.

Вот более простой подход для отображения этих данных:

Источник данных (таблица) -> ORM / Пользовательский объект данных или коллекция-> Экземпляр объекта / коллекции на странице-> Пользовательский интерфейс.

Ваш пользовательский интерфейс в идеале должен привязываться к тому экземпляру объекта, который гипотетически будет сохранен (и обернут в публичное или защищенное свойство) в любой из объектов состояния, предоставленных asp.net на странице (Session / AppState / ViewState).

Обновления в пользовательском интерфейсе могут распространяться через транзакцию (с использованием System.Transaction.TransactionScope) к объекту, хранящемуся в состоянии, а также к источнику данных, что будет гарантировать, что ваш источник данных совпадает с вашими отключенными данными, при обеспечении постепенного ухудшения в случае отказа.

При доступе к экземпляру объекта / коллекции из ваших исполняемых / других страниц общедоступное свойство или переменная облегчит эту задачу.

Эта концепция устраняет необходимость проходить контроль. Вы только передаете объекты данных назад и вперед между объектами / элементами пользовательского интерфейса, которые их используют или выполняют действия от их имени.

Обновления, которые происходят внутри двух или более компонентов времени выполнения, могут быть объявлены другим с помощью шаблона Observer или простых делегатов ...

1 голос
/ 15 декабря 2010

Чтобы ответить на ваш вопрос ...

Enabled='<%# ToggleControl(FindControl("txtSomething") as WebControl,new SomeAssessor().EnabledWhenIdXyz) %>'

Вы можете использовать этот помощник в своем коде

public bool ToggleControl(WebControl control, Func<WebControl, bool> assessControl)
{
    return assessControl(control);
}

И это отдельный класс, который вы упомянули

public class SomeAssessor
{
    public bool EnabledWhenIdXyz(WebControl control)
    {
        return control.ID == "txtSomething2";
    }
}

Предлагаемая идея: вместо этого вы можете получить IEnumerable<SomeModel> из вашего источника данных для вашего вида сетки.Объект SomeViewModel - это преобразование исходных данных в точную «форму», необходимую для вашего элемента управления.

public class SomeModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class SomeViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Enabled { get; set; }
}

Создайте преобразователь, который преобразует модель в представление, и здесь может произойти оценка Enabled.

public interface IMapper<TModel, TViewModel>
{
    TViewModel MapModelToView(TModel source);
}

public class SomeMapper : IMapper<IEnumerable<SomeModel>, IEnumerable<SomeViewModel>>
{
    public IEnumerable<SomeViewModel> MapModelToView(IEnumerable<SomeModel> source)
    {
        return source.Select(x => new SomeViewModel
                                      {
                                          Id = x.Id,
                                          Name = x.Name,
                                          Enabled = true //call to your method and resolve
                                      });
    }
}

Затем запросите данные как IEnumerable<SomeModel>, отобразите их и используйте IEnumerable<SomeViewModel> в качестве источника данных GridView.

Затем вы можете написать следующую оценку в текстовое поле:

Enabled='<%# Eval("Enabled")%>'
0 голосов
/ 14 декабря 2010

Вы можете получить любой элемент управления, добавить новое свойство, такое как «AuthExpression», и использовать выражение привязки данных, которое вы можете оценить с помощью метода DataBinder.Eval.

Или вы можете создать ASP.NET AJAXЭлемент управления extender, который выполняет эту работу для любого элемента управления, который вам нравится: любой элемент управления, расширенный расширителем, обнаруживает выражение привязки данных, которое определяет, что элемент управления должен быть включен или отключен.

Я надеюсь, что это ответ на ваш вопрос!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...