2012-02-24 3 views
2

J'ai un modèle qui a un nombre d'attributs qui peut être ou ne pas être nul, selon que les données sont disponibles pour ces attributs spécifiques sur un serveur distant.Accès et modification des éléments xaml avec Reflection en C#

Je construis une application Windows Phone simple qui donne des versions plus facilement accessibles de ces informations sur un téléphone mobile. J'ai trouvé que dans le cas où les propriétés du modèle ci-dessus ne sont pas définies, la valeur n'apparaît pas (affiche un blanc), mais l'étiquette apparaît toujours. Après avoir considéré un certain nombre de différentes alternatives pour cela (y compris des quantités massives d'instructions if, ugh), j'ai décidé que si je définissais le nom d'attributs spécifiques dans le xaml pour correspondre aux propriétés du modèle de données que je cherchais À, je puis en temps réel avoir le système analyser les propriétés du modèle de données, et les éléments de mon xaml. Si une propriété de mon xaml correspondait au nom de la propriété dans mon modèle et que le modèle était null, je pourrais réduire la visibilité. Si le modèle n'était pas nul, rendez-le visible. Ainsi, je pourrais avoir une solution propre et dynamique qui ne montrerait que les données réellement disponibles.

est ici le code

PropertyInfo[] properties = data.GetType().GetProperties(); 

foreach (PropertyInfo property in properties) 
{ 

    FieldInfo view = this.GetType().GetField(property.Name); 

    if (view != null) 
    { 
     if (property.GetValue(data, null) == null) 
     { 
      object aView = view.GetValue(this); 
      aView.GetType().GetProperty("Visibility").SetValue(aView, "Collapsed", null); 
     } 
     else 
     { 
      object aView = view.GetValue(this); 
      aView.GetType().GetProperty("Visibility").SetValue(aView, "Visible", null); 
     } 
    } 
} 

Malheureusement, je frappe un accroc. Je n'arrive pas à comprendre comment accéder aux éléments xaml. J'ai essayé d'utiliser

this.GetType().GetProperties() 
this.GetType().GetFields() 
this.GetType().GetMembers() 

Pour trouver les éléments que je suis à la recherche, mais ils ne figurent pas dans l'un de ces. Y a-t-il quelque chose qui me manque?

Y a-t-il une meilleure façon de faire cela qui soit plus belle?

Merci d'avance pour votre aide.

+0

Je pense que vous allez à ce sujet dans le mauvais sens. Vous devez suivre le modèle MVVM et lier la visibilité à une propriété de votre modèle qui détermine si vos données sont disponibles. –

+0

@JeffMercado Vous n'avez pas besoin de suivre le modèle MVVM! Si c'est une application simple, un peu de code-behind ne fera pas de mal. – ColinE

+0

Si vous avez une suggestion pour ce faire, je suis tout ouïe! Idéalement, le StackPanel qui contient tous les éléments liés à cet élément serait visible/effondré –

Répondre

1

Vous pouvez créer un convertisseur personnalisé utilisé dans une expression de liaison de visibilité pour chaque élément. Ce convertisseur peut vérifier la propriété transmise et, si elle est nulle, renvoyer Collapsed comme valeur, sinon Visible.

Similaire à ce que vous faites, mais tout déclaratif, et beaucoup plus rapide que l'utilisation de la réflexion.

Voici un exemple - http://digitalmoto.net/blog/2011/02/28/null-object-to-visibility-converter/

+0

Semble intéressant, avez-vous un code que vous pourriez suggérer pour cela? –

+0

J'ai ajouté un exemple. J'essaie de trouver un moyen de l'automatiser afin que vous n'ayez pas besoin d'ajouter une liaison de visibilité à chaque élément. Utilisez-vous toujours cela sur le même type d'élément? c'est-à-dire sont-ils tous des TextBlocks ou des Labels? – devdigital

+0

StackPanels serait un pari sûr, habituellement, j'ai deux textBlocks, un pour l'étiquette, un pour la valeur, enveloppé dans un stackPanel horizontal –

3

Si vous avez nommé éléments dans votre XAML comme suit:

<Grid> 
    <TextBlock x:Name="txt" /> 
</Grid> 

Vous pouvez les trouver via la méthode FindName:

TextBlock txt = this.FindName("txt") as TextBlock; 

Aucune réflexion est requis!

+0

Founds génial, sauf que je pense que je vais toujours avoir besoin de réflexion pour obtenir les noms de toutes les propriétés du modèle pour l'exécuter. Ne pas dire que ça ne marcherait pas, dire simplement que j'aurais encore besoin d'une réflexion de l'autre côté. –

+0

@JamieStarke OK - il semble que MVVM soit une meilleure solution pour votre problème. En passant - comme vous êtes nouveau sur Stack Overflow, n'oubliez pas de remettre en question toutes les réponses que vous trouvez utiles. Vous n'avez pas à les marquer comme réponse si elles ne sont pas un ajustement parfait, mais les upvotes sont bonnes :-) – ColinE

+0

Oh, je prévois de rehausser, mais je ne peux pas jusqu'à ce que j'obtiens 15 points. –