La liaison de données pour une méthode en WPF
J'ai de la difficulté databinding un TextBox.Text
de la propriété à une méthode de l'objet. L'idée est de permettre à l'utilisateur d'écrire dans un TextBox
un nom de fichier et puis avoir un TextBlock
de sortie que l'extension du fichier.
class GetFileInfo
{
public string GetFileExtension(string fileName)
{
return Path.GetExtension(fileName);
}
}
Voici mon code XAML:
<Window.Resources>
<ObjectDataProvider x:Key="getFileInfo" MethodName="GetFileExtension" ObjectType="{x:Type local:GetFileInfo}">
<ObjectDataProvider.MethodParameters>
<sys:String>abc.text</sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<StackPanel>
<TextBox Name="textBox1">
<TextBox.Text>
<Binding Source="{StaticResource getFileInfo}" Path="MethodParameters[0]" BindsDirectlyToSource="True" UpdateSourceTrigger="PropertyChanged" />
</TextBox.Text>
</TextBox>
<TextBlock Name="textBlock1" Text="{Binding Source={StaticResource getFileInfo}}"/>
</StackPanel>
Pour une raison quelconque, il n'est pas de faire quoi que ce soit. Anyknow pourrait préciser ce que peuvent être les raisons?
Voici ce que je vois sur le concepteur et quand je lance l'application:
le texte d'alt http://img64.imageshack.us/img64/6922/f0rki14feo3oa3groxm5kgm.png
Et voici ce qui se passe lorsque j'essaie de configurer d'autres de texte au moment de l'exécution:
le texte d'alt http://img684.imageshack.us/img684/1057/b52pnq1dm4i23qivizvpaqq.png
Ici, l'erreur est donnée par de débogueur lorsque vous tentez de définir d'autres types de texte au moment de l'exécution:
Système.De Windows.Erreur de données: 8 : Impossible d'enregistrer la valeur de la cible vers la source. BindingExpression:Path=MethodParameters[0]; DataItem='ObjectDataProvider' (HashCode=2207369); élément cible est "champ de texte" (Nom= "textBox1"); de la propriété cible est "Texte" (de type 'String') ArgumentException:'Système.ArgumentException: Objet de type " MME Internes.Les données.PropertyPathWorker+IListIndexerArg " ne peuvent pas être convertis en type 'System.Int32'.
au Système.RuntimeType.TryChangeType(la valeur de l'Objet, Binder Binder, CultureInfo culture, Boolean needsSpecialCast)
au Système.RuntimeType.CheckValue(la valeur de l'Objet, Binder Binder, CultureInfo culture, BindingFlags invokeAttr)
au Système.De la réflexion.MethodBase.CheckArguments(Object[] paramètres, Binder Binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
au Système.De la réflexion.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder Binder, Object[] paramètres, CultureInfo culture, skipVisibilityChecks Booléens)
au Système.De la réflexion.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder Binder, Object[] paramètres, CultureInfo culture)
au Système.De la réflexion.RuntimePropertyInfo.SetValue(Object obj, la valeur de l'Objet, BindingFlags invokeAttr, Binder Binder, Object[] index, CultureInfo culture)
au MME Internes.Les données.PropertyPathWorker.SetValue(Objet élément, la valeur de l'Objet)
au MME Internes.Les données.ClrBindingWorker.UpdateValue(la valeur de l'Objet)
au Système.De Windows.Les données.BindingExpression.UpdateSource(la valeur de l'Objet)'
+1 pour poser une question qui va aider beaucoup de personnes qui ne comprennent pas la liaison de données.
OriginalL'auteur devoured elysium | 2010-02-21
Vous devez vous connecter pour publier un commentaire.
Alors qu'il est possible d'utiliser
Binding
d'appeler une méthode, et obtenez sa valeur de retour, il n'est pas simple. C'est beaucoup plus simple de se lier à des propriétés et de l'utilisation de la combinaison de la liaison et de la notification de changement pour obtenir le résultat que vous recherchez.Créer une classe avec deux propriétés,
Filename
etExtension
.Filename
est juste une lecture/écriture de la chaîne de propriété.Extension
est une chaîne en lecture seule propriété dont getter appelle la méthode que vous essayez d'appeler.Maintenant faire la classe en œuvre
INotifyPropertyChanged
, parce que si une propriété peut changer dans le code, il a besoin d'une manière de dire à la liaison qu'il a fait. Faire le setter de laFilename
bien informer les liaisons qui lesExtension
propriété a changé.Ajouter un
Binding
à unTextBox
qui se lie à laFilename
de la propriété à l'aide de laTwoWay
mode. Ajouter unBinding
à unTextBox
qui se lie àExtension
à l'aide de la valeur par défautOneWay
mode.La séquence des événements est:
Filename
dans un liéTextBox
et appuie sur TAB.TextBox
perd le focus.Binding
's mode,TwoWay
, et il utilise le comportement par défaut de la mise à jour de la source lorsque la cible perd le focus, c'est ce qu'il fait.Binding
les mises à jour de la source par l'appel de laFilename
setter.Filename
setter soulèvePropertyChanged
.Binding
poignéesPropertyChanged
, regarde son argument, et voit que leExtension
propriété a changé.Binding
appelle laExtension
propriété de l'acquéreur.Extension
du bien getter appelle la méthode pour déterminer l'extension deFilename
, et le renvoie à l'Binding
.Binding
les mises à jour de sa cibleTextBox
avec la nouvelle valeur deExtension
.C'est le concept de base de données sous-jacente de la liaison et le pattern MVVM. Une fois que vous comprenez cela, il devient une seconde nature, et WPF développement devient environ dix millions de fois plus facile.
OriginalL'auteur Robert Rossney
Ressemble vous avez besoin pour obtenir une compréhension de MVVM , consultez cet article classique
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
OriginalL'auteur Jobi Joy
De liaison de données nécessite la
NotifyPropertyChanged
événement qui sera appelée lorsque la source est mise à jour. Dans ce cas, vous souhaitez envelopper cette fonction à appeler un get/set:Si vous préférez le faire dans la bonne WPF façon, ce doit être le code que vous devez utiliser. Il n'y a rien de fou dans le code ci-dessus, si vous l'apprendre, il va vous aider à jamais avec WPF. en tout MVVM base de WPF, vous pouvez voir ce petit morceau de code. Donc, il vaut un apprentissage.
Je vois votre point de vue. Je vais l'apprendre de cette façon-là.
Mais où faut-il mettre? Devrait FileExtension être une Fenêtre de propriété?
OriginalL'auteur apandit
Ok, on dirait que c'est un bogue lors de l'exécution de WPF 4.0, comme on peut le voir dans les commentaires ici.
Lors de la compilation en 3.5, il fonctionne très bien ici.
OriginalL'auteur devoured elysium
Est le
DataContext
ensemble? Dans votre code-behind, avez-vous définissez la valeur de votreTextBlock
"saadsas" (je ne peux que deviner), qui a brisé le databinding?OriginalL'auteur Dave