web-dev-qa-db-fra.com

"{Binding Path =.}" Et "{Binding}" sont-ils vraiment égaux

Dans mon projet WPF, j'ai un ListBox qui affiche les éléments d'un List<string> collection. Je voulais rendre le texte de ces éléments modifiables, j'ai donc enveloppé chacun d'eux dans un ItemTemplate avec une TextBox (ce n'est peut-être pas la meilleure façon, mais je suis nouveau sur WPF). J'avais du mal à simplement lier la propriété Text des TextBoxes à la valeur de chaque élément. Je suis finalement tombé sur un exemple utilisant un seul point ou période pour sa propriété Path ({Binding Path=.}):

<ListBox ItemsSource="{Binding ElementName=recipesListbox,Path=SelectedItem.Steps}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Path=.}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Cependant, je ne comprends pas pourquoi simplement utiliser {Binding} n'a pas fonctionné.

Il a déclenché une exception " La liaison bidirectionnelle nécessite Path ou XPath ", comme selon Microsoft :

[...] un chemin point (.) peut être utilisé pour se lier à la source actuelle. Par exemple, Text = "{Binding}" est équivalent à Text = "{Binding Path =.}"

Quelqu'un pourrait-il faire la lumière sur ce comportement ambigu?

EDIT: De plus, il semble {Binding Path=.} ne donne pas nécessairement une liaison bidirectionnelle, car la modification du texte et le déplacement du focus ne mettent pas à jour la source sous-jacente (la même source a également des propriétés affichées et modifiées avec succès sur un contrôle DataGrid). Il me manque définitivement quelque chose ici.

45
Fueled

Le point de l'exception est probablement que vous ne pouvez pas lier une source de liaison elle-même, il essaie donc de vous empêcher de créer une liaison qui ne se comporte pas comme vous le souhaiteriez. En utilisant {Binding Path=.} vous venez de tromper la gestion des erreurs.

(Il n'est pas rare non plus que cette documentation soit erronée ou inexacte, bien que j'aime beaucoup la documentation MSDN en général car elle contient généralement les points cruciaux qui nous intéressent)

27
H.B.

La documentation indique que {Binding} est équivalent à {Binding Path=.}. Cependant c'est pas équivalent à {Binding Path} comme vous l'avez tapé. Si vous incluez la propriété Path, vous devez l'affecter à quelque chose, que ce soit Path=. ou Path=OtherProperty.

21
ceyko

Ce ne sont pas les mêmes. Si vous liez ceci où ConsoleMessages est une chaîne ObservableCollection avec juste {Binding}, vous obtenez une "liaison bidirectionnelle nécessite Path ou XPath". exception où fonctionne {Binding Path =.}. C'est avec WPF 4.0 ...

    <ItemsControl x:Name="ConsoleOutput" ItemsSource="{Binding ConsoleMessages, Mode=OneWay}" MaxHeight="400">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Path=.}" BorderThickness="0" Margin="0" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Mon 2p vaut ...

7
user844705

En bref, la différence entre les deux est analogue à la différence entre le passage par valeur traditionnel et le passage par référence. (ARY - Quelle est la différence entre passer par référence et passer par valeur? )

Cependant, je ne comprends pas pourquoi l'utilisation de {Binding} n'a pas fonctionné (cela a déclenché une exception "La liaison bidirectionnelle nécessite Path ou XPath")

Supposons ici pour l'instant que {Binding} peut être utilisé pour la liaison bidirectionnelle. En général {Binding} crée un lien basé sur une valeur avec datacontext qui ne permet pas de mettre à jour le datacontext.

Tandis que {Binding Path=.} crée un lien basé sur la référence avec la zone mémoire référencée par le 'Path' qui permet de mettre à jour la valeur par référence (dans ce cas 'dot' le contexte de données actuel).

J'espère que cela t'aides!

4
Vwake