2010-12-14 9 views
1

J'ai un contrôle TextBox Asp.Net dont la propriété enabled que je dois évaluer en utilisant une classe distincte (de la code derrière la page contenant). La façon dont je veux faire est:Comment inclure une référence automatique à un contrôle serveur dans un appel de méthode externe?

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

La raison pour laquelle je dois passer une référence au contrôle d'appel est de voir s'il y a d'autres propriétés je besoin à considérer avant de le désactiver. Le mot clé "this" fait toutefois référence à la page dans son ensemble. Et puisque mon TextBox peut être dans un FormView, ou GridView, je ne peux pas simplement obtenir le contrôle en examinant 'page.myTB'. Je ne veux pas avoir à commencer à labourer GridViews sur le fichier de classe de réception juste pour récupérer une référence à la TextBox.

Est-ce que quelqu'un sait comment se référer à la commande en ligne de cette façon?

EDIT 1: Cela devra être fait pour plusieurs types de contrôle serveur différents, tels que ListBox, CheckBox, RadioButtonList, etc.

EDIT 2: Le meilleur que je suis venu avec jusqu'à présent est:

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

ce qui n'est pas trop élégant, mais cela me donne l'auto-référence dont j'ai besoin.

+0

Thats fait un dilemme intéressant. Habituellement, quand j'ai besoin de mon contrôle pour avoir une certaine logique je le sous-classerais à mon propre TextBox spécial qui a la logique à l'intérieur de lui-même. Après tout, c'est quoi OO! –

+0

Normalement, nous ferions cela mais le comportement que nous voulons est applicable à tous les contrôles d'entrée, donc nous voudrions éviter de devoir sous-classer chaque contrôle d'entrée qui existe (et en exiger de nouveaux pour le faire aussi). Nous envisagions également d'utiliser des adaptateurs Web, mais c'est un peu plus complexe. –

Répondre

0

Vous pouvez dériver n'importe quel contrôle, ajouter une nouvelle propriété comme "AuthExpression" et utiliser une expression de liaison de données que vous pouvez évaluer avec la méthode DataBinder.Eval.

Ou vous pouvez créer un contrôle d'extension ASP.NET AJAX qui fait ce travail pour tout contrôle que vous aimez: tout contrôle étendu par l'extenseur évalue une expression de liaison de données qui détermine que le contrôle doit être activé ou désactivé.

J'espère que cela répond à votre question!

1

Je pense qu'il y a un problème de séparation UI/Data/Code.

Je pense que vous devez écrire un wrapper pour votre source de données afin que toutes les données soient disponibles avant de se lier. Cela évitera d'avoir à trouver des contrôles imbriqués et ainsi de suite ...

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

Vous ne voulez jamais passer des contrôles à un autre objet. La raison en est que si vous devez modifier l'interface utilisateur de l'application, vous devez reconstruire tout ce qui a une référence à cet élément de l'interface utilisateur.

Voici une approche plus simple pour afficher les données:

DataSource (tableau) -> ORM/données personnalisées Objet ou Collection-> instance de l'objet/Collection Sur Page-> UI. Votre interface utilisateur a besoin de se lier à l'instance d'objet qui sera hypothétiquement sauvegardée (et enveloppée dans une propriété publique ou protégée) à l'un des objets d'état fournis par asp.net sur la page (Session/AppState/ViewState) .

Les mises à jour de l'interface utilisateur peuvent être propagées via une transaction (using System.Transaction.TransactionScope) vers l'objet stocké dans l'état ainsi que la source de données, ce qui garantit que votre source de données est identique à vos données déconnectées , tout en offrant une dégradation gracieuse en cas de défaillance.Lorsque vous accédez à l'instance de l'objet/collection par vos pages d'exécution/autres, une propriété publique ou variable facilitera cet objectif.

Ce concept supprime le besoin de passer des contrôles. Vous ne faites que passer des objets de données entre les éléments objets/ui qui les consomment ou prendre des mesures en leur nom.

mises à jour qui se produisent à l'intérieur de deux ou plusieurs composants d'exécution peuvent être annoncés à d'autres via le modèle d'observateur ou des délégués simples ...

1

Pour répondre à votre question ...

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

Vous pouvez utiliser cette aide dans votre code derrière

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

C'est la classe séparée vous avez mentionné

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

Voici une idée suggérée à faire à la place: Vous pourriez avoir un IEnumerable<SomeModel> retourné à partir de votre source de données pour votre gridview. L'objet SomeViewModel est une transformation des données d'origine en une forme exacte requise pour votre contrôle.

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; } 
} 

Créez un mappeur qui convertit le modèle en vue, et ici l'évaluation Activé peut se produire.

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 
             }); 
    } 
} 

requête ensuite vos données IEnumerable<SomeModel>, map, et utiliser IEnumerable<SomeViewModel> comme source de données du GridView.

Vous pouvez alors écrire l'évaluation suivante dans votre zone de texte:

Enabled='<%# Eval("Enabled")%>'