Débutant - confus au sujet de la liaison et des ressources en WPF
J'essaie d'apprendre à WPF, mais je trouve qu'il est très difficile de comprendre les liaisons, les "ressources" chose, et la création de l'objet.
Mon fond est en C++/MFC et C#-Winforms.
Mes questions:
-
La plupart des exemples que je vois dans le code XAML (dans MSDN et dans deux autres WPF livres que j'ai lu) utilisation StaticResource dans l'expression de liaison. Ces liés en aucune façon à des membres statiques? Ou est-ce juste un nom trompeur? Lorsqu'il est fait référence à un objet en tant que StaticResource, lorsqu'il est instancié?
-
Aussi loin que je peux voir StaticResources sont utilisés avec les "choses", défini dans la section "Ressources" de l'app/fenêtre/de contrôle etc.
Maintenant, ces Ressources sections sont très confus pour moi.
Qu'est-ce exactement sont-ils? De par mon expérience dans MFC ces ont été des icônes, des cordes, etc. Cependant, à en juger par tous les exemples que j'ai vu, dans WPF ceux-ci semblent être essentiellement un "dépotoir" pour
a tous les types d'objet global définitions dans le balisage (styles, les modèles de données, etc)
b tous les types d'objet global instanciations dans le balisage
Suis-je la corriger? Cela me semble très salissant.
Il porte essentiellement sur l'apprentissage de toutes sortes de semi-DSLs en XAML (pour la définition de styles, de définir des modèles de données, pour créer des objets, etc), et de les coller ensemble dans le même lieu.
Je continue de penser à quelque chose comme l'édition du fichier de ressources (.rc) dans le MFC à la main. Au moins là, les articles étaient bien séparées et la syntaxe pour chaque ressource est relativement simple. -
De lier les deux questions précédentes: Quand j'définir une instance de l'objet dans la section des Ressources, et plus tard de référence à partir d'un StaticResource de liaison, quand est-il exactement instancié?
MSDN dit (dans "Comment faire: Rendre les Données Disponibles pour la Liaison en XAML"):
une façon, vous pouvez faire l'objet
disponibles pour la liaison est de le définir
en tant que ressource
Cependant, ce n'est pas très clair. Que signifient-ils disponibles? Signifient-ils créés? Signifient-ils raccordés à la liaison sous-système? Et quand exactement est l'objet créé?
De jouer avec un exemple simple, j'ai vu que WPF semble pour créer cet objet pour moi quand il essaie de joindre la liaison. Et c'est encore plus confus.
EDIT:
Après la clarification par karmicpuppet ci-dessous, je suis encore confus quant à la façon dont cela est relié à la Liaison.
Supposons que j'ai dans mes ressources:
<local:Person x:Key="MyPerson" Name="Title"/>
(où la Personne est une classe avec une propriété de Nom) puis dans la fenêtre, j'ai:
<TextBlock Text="{Binding Source={StaticResource MyPerson}, Path=Name}"/>
1) Qu'est-ce que cela? Est-il passe par les mêmes étapes - la recherche de la ressource et ensuite l'appliquer à la propriété Text? Le MyPerson objet est créé au moment de la création de la Fenêtre, ou plus tard?
2) Dois-je utiliser le mécanisme de Liaison pour lier le Nom de la propriété? Je ne peux pas lier directement comme vous l'avez fait ci-dessus avec myBrush? Pourquoi je ne peux pas faire quelque chose comme cela?
<TextBlock Text="{StaticResource MyPerson, Path=Name}"/>
Est-ce juste un manque de clairvoyance de la part du cadre? Je pense que je suis absent très grand ici, mais je n'arrive pas à comprendre ce que...
3) j'ai essayé d'utiliser DynamicResource, mais je suis très confus au sujet de chaque étape j'ai pris.
a) Ajout d'un DependencyObject avec une DependencyProperty au-dessus de ma classe de Fenêtre unique dans le code (est-ce DependencyObject nécessaire?)
public class SomeText : DependencyObject
{
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string), typeof(SomeText), new UIPropertyMetadata(0));
}
b) Ajout d'une instance de Windows.Ressources (est-ce nécessaire avec DynamicResource? MSDN semble dire que non, mais si je ne peux pas comprendre comment le faire la prochaine étape dans le code XAML)
c) j'ai essayé les deux:
Text="{Binding Source={DynamicResource HeaderText}, Path=Header}"
Qui m'a donné une exception, et
Text="{DynamicResource HeaderText}"
Mais je ne comprenais pas où mettre le chemin d'accès à la propriété d'en-Tête.
C'est ma 5ème ou alors tenter de bricoler avec WPF ces derniers temps, et chaque fois que je suis perplexe par cette apparemment simple des choses qui ne fonctionnent pas. J'ai lu 2 livres et j'ai vraiment essayer de comprendre les articles MSDN, cependant, elles sont d'aucun secours.
- Attendez jusqu'à ce que vous vous trouvez dans le besoin d'un on-the-fly animation..
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, un commentaire général:
WPF est difficile à apprendre. Il est difficile à apprendre car il y a plusieurs différentes fondamentalement nouveaux concepts que vous devez obtenir votre tête autour de en même temps. La lutte que vous êtes ayant droit maintenant, c'est que vous êtes en train d'apprendre au moins trois choses à la fois:
XamlReader
(et en particulier les extensions de balisage) désérialise XAML dans les objets.FrameworkElement
's dictionnaires de ressources de travail.Quelque chose comme ceci:
est de s'engager (au moins) trois technologies très différentes en même temps. Ces technologies sont toutes conçues pour être aussi souple que possible, ce qui ne fait que les rendre plus déroutant pour le débutant. L'idée qu'une source de liaison peut être n'importe quoi: c'est difficile à comprendre. L'idée qu'une extension de balisage est un type de format de sérialisation qui prend en charge la récursivité: assez simple à comprendre, en principe, mais un peu déroutant lorsque vous commencez à travailler avec des exemples du monde réel. L'idée qu'un dictionnaire de ressources peut contenir à peu près tout, et que les ressources algorithme de recherche essentiellement des ressources pouvant être héritées: encore une fois, assez simple dans son concept, mais facile de perdre le fil de quand vous êtes à essayer de comprendre la liaison de données et XAML dans le même temps.
C'est frustrant, parce que quelque chose qui est conceptuellement simple - "je veux lier ce contrôle à une propriété d'un objet que j'ai créé" - exige que vous comprenez beaucoup de choses avant que vous pouvez réellement exprimer dans le code XAML.
La seule solution est d'être patient, et assurez-vous de comprendre les choses au niveau le plus bas possible. Lorsque vous voyez ceci:
vous devriez être capable de penser, "Qui va invoquer la
StaticResource
balisage gestionnaire d'extension, qui récupère un objet à partir d'un dictionnaire de ressources à l'aide de la cléMyPerson
lorsque le code XAML est désérialisé.Il est extrêmement difficile au premier abord. J'ai mis au point un logiciel professionnel depuis 35 ans, et j'ai trouvé WPF pour être les plus difficiles de la technologie de plate-forme que je n'ai jamais appris par une marge considérable. Mais tout ça est difficile à apprendre parce que c'est incroyablement fonctionnel et flexible. Et le résultat de l'apprentissage, il est énorme.
À l'adresse d'un couple de questions que karmicpuppet n'a pas:
Qui n'a pas changé. Vous pouvez créer des fichiers de ressources de WPF et de les charger dans des objets lors de l'exécution. Il ya beaucoup de façons différentes de le faire - vous pouvez créer des ressources dans l'éditeur de ressources et de les charger via la
Properties.Resources
objet, vous pouvez ajouter des fichiers d'images (par exemple) pour le projet, les ont compilés en tant que ressources, et de les charger à l'aide de leurs URI, et il ya beaucoup d'autres façons que je ne connais pas.Les ressources disponibles pour
FrameworkElement
s par l'intermédiaire de leurs dictionnaires de ressources sont une chose différente. Eh bien, en quelque sorte. Voici un exemple:Cela crée une
Image
objet et l'ajoute à laWindow
's dictionnaire de ressources avec une clé deMyImage
Vous pouvez alors faire référence à cet objet via leStaticResource
extension de balisage XAML, ou leFindResource
méthode dans le code.Réglage de la
Source
attribut sur laImage
élément XAML aussi rend leXamlReader
utiliser leResourceManager
pour lire les données d'image du projet est compilé ressources à l'exécution lorsqu'il crée leImage
objet.Dans la pratique, c'est loin d'être aussi confus que lorsque vous êtes le premier apprentissage de WPF. Je n'ai jamais obtenir des ressources qui
ResourceManager
les charges et les ressources stockées dans les dictionnaires de ressources mélangés.Tout objet défini par un élément XAML est créé lors de l'
XamlReader
lit l'élément. Donc:instancie une nouvelle
Person
objet et l'ajoute à laWindow
's dictionnaire de ressources avec une clé deMyPerson
. C'est exactement équivalente à le faire dans lesWindow
le code-behind:Alors pourquoi ne pas vous venez de le faire dans le code-behind? Deux raisons:
Première, c'est cohérent. Si vous définissez vos ressources dans le code XAML, vous avez seulement besoin de regarder dans les fichiers XAML pour trouver quelles sont vos ressources. Si vous définir dans le XAML et le code-behind, vous avez à regarder à deux endroits.
Deuxième, l'IDE sait sur les ressources que vous définissez dans le XAML. Si vous tapez
dans votre XAML, l'IDE vous permettra de savoir si vous n'avez pas défini, quelque part dans la hiérarchie des dictionnaires de ressources, une ressource dont la clé est
MyPerson
. Mais cela ne veut pas connaître les ressources que vous avez ajoutés dans le code, et donc, même si la ressource peut effectivement être trouvable au moment de l'exécution, l'IDE de le signaler comme un problème.Pensez-y de cette façon: tous les FrameworkElements (Fenêtres, Boutons, d'autres Contrôles, etc), ainsi que de l'objet Application, contient un Dictionnaire de Ressources. Chaque fois que vous définissez une ressource dans le code XAML comme indiqué ici:
C'est comme de faire quelque chose comme cela dans le code:
Vous pouvez mettre toutes sortes d'objets comme des Ressources. Tout ce que vous voulez ré-utiliser dans votre application, vous pouvez la définir comme une Ressource.
Maintenant, lorsque vous utilisez un "{StaticResource}", comme suit:
C'est comme dire WPF pour la recherche de correspondants "myBrush" des ressources et de l'appliquer à l'arrière-plan de la propriété. Ce qui va arriver, c'est WPF sera d'abord rechercher la ressource dans le Bouton dictionnaire de ressources, et si il ne l'est pas sera à la recherche de sa mère, puis de son parent parent, et ainsi de suite, jusqu'à les ressources de l'application.
"Statique" chose "StaticResource" juste le distingue de l'autre type de ressources, de recherche appelé "DynamicResource". La différence entre les deux est répondu dans ce lien.
Lorsqu'il est appliqué à la Liaison, il fonctionne également de la même façon. Dire, par exemple, vous avez la ressource suivante dans votre code XAML:
et l'a utilisé comme:
Dans ce cas, ce qui va arriver à quelque chose comme ceci:
Encore une fois, le "{StaticResource}" les marques dans le XAML dit WPF pour la recherche de la ressource correspondante et la définir comme la valeur de la propriété. Dans ce cas, la propriété est la Liaison la "Source" de la propriété.
C'est l'essentiel. Espérons que vous trouverez ce utile