2010-12-01 11 views
0

Lorsque vous utilisez DataTemplate pour un élément ListBox, mon application se bloque et déclenche une exception dans la fenêtre de sortie. Les détails suivent.Mode de liaison pour l'élément dans la zone de liste

Modifier le modèle:

<DataTemplate x:Key="EditOnlyTemplate"> 
    <Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="5" Background="Beige"> 
     <StackPanel Orientation="Horizontal"> 
      <StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
       <TextBox Width="300" FontSize="25" Foreground="Goldenrod" Text="{Binding XPath=/doc/dob/text, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged, diag:PresentationTraceSources.TraceLevel=High}" /> 
       <TextBox Width="300" FontSize="25" Foreground="Blue" Text="{Binding XPath=/doc/dob/group, UpdateSourceTrigger=PropertyChanged}" /> 
       <TextBox Width="300" FontSize="25" Foreground="Green" Text="{Binding XPath=/doc/dob/filter, UpdateSourceTrigger=PropertyChanged}" /> 
       <Button Content="Save" Click="btnSave_Click" Width="40" HorizontalAlignment="Left" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"/> 
      </StackPanel> 
     </StackPanel> 
    </Border> 
</DataTemplate> 

J'utilise le code suivant derrière pour gérer un clic de bouton et changer mon DataTemplate sur mon ListBox article d'un qui affiche simplement les données liées (c.-à-modèle « Détails ») à un où je peux modifier les données liées (c.-à-d., «Modifier» le modèle).

private void btnEdit_Click(object sender, RoutedEventArgs e) 
{ 
    Button btn = (Button)sender; 
    //command contains the list item 
    ContentControl itm = (ContentControl)btn.CommandParameter; 
    itm.ContentTemplate = this.FindResource("EditTemplate") as DataTemplate; 

} 

La chose à noter au sujet de mon EditTemplate est le mode de liaison de la première zone de texte - il est réglé sur OneWayToSource. C'est ce qui cause le problème, en cliquant sur le bouton "Modifier" qui permute dans ce modèle. Si je change le mode à "TwoWay" (le mode par défaut pour le TextBox), il n'y a pas de problème. En outre, si j'utilise une copie de ce modèle dans un autre endroit de la page, placé pendant la conception - pas via le code - et non dans un élément ListBox, mais dans un ContentControl, le mode OneWayToSource fonctionne comme prévu.

L'exception levée dans mon scénario cassé est le suivant:

System.Windows.Data Warning: 104 : BindingExpression (hash=48690759): At level 0 - for XmlElement.InnerText found accessor ReflectPropertyDescriptor(InnerText) 
    System.Windows.Data Warning: 100 : BindingExpression (hash=48690759): Replace item at level 0 with XmlElement (hash=21889970), using accessor ReflectPropertyDescriptor(InnerText) 
    System.Windows.Data Warning: 86 : BindingExpression (hash=48690759): Update - got raw value '' 
    System.Windows.Data Warning: 90 : BindingExpression (hash=48690759): Update - using final value '' 
    System.Wi 

ndows.Data Warning: 98 : BindingExpression (hash=48690759): SetValue at level 0 to XmlElement (hash=21889970) using ReflectPropertyDescriptor(InnerText): '' 
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll 
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=/InnerText; DataItem='XmlDocument' (HashCode=33583636); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') InvalidOperationException:'System.InvalidOperationException: Dispatcher processing has been suspended, but messages are still being processed. 
    at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value) 
    at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value) 
    at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value) 
    at System.Windows.Data.BindingExpression.UpdateSource(Object value)' 

Je soupçonne que la zone de liste est en quelque sorte la cause, mais ne peut pas comprendre pourquoi, à l'exception de bug possible. J'utilise le .Net Framework 3.5 avec toutes les mises à jour actuelles, sur Windows XP. Est-ce que quelqu'un voit quelque chose qui cloche manifestement avec ce que je tente de faire?

Répondre

0

En ignorant l'exception et en vous aidant à surmonter votre implémentation actuelle, vous devriez utiliser un DataTemplateSelector. Voici un sample qui se déroule sur un ListBox.

+0

Salut Aaron, Merci pour le conseil. J'utiliserai sûrement le DataTemplateSelector à l'avenir, mais je ne suis pas sûr de l'impact que cela aura sur ce problème que je vois. Il me semble que l'utilisation prévue de DataTemplateSelector est d'afficher différents types d'éléments dans la ListBox, alors que ce que j'essaye de faire est de mettre en œuvre un "mode" d'utilisation différent pour les données liées. Je vais essayer. – Bill

0

OneWayToSource essaie de mettre à jour vos données de liaison, ce qui n'est probablement pas possible. La liaison OneWay devrait fonctionner correctement.

+0

Bonjour Grozz, Vous avez raison de dire que, pour une raison quelconque, changer le DataTemplate de cette manière crée un problème de mise à jour de la source. Toutefois, si j'essaie d'utiliser TwoWay au lieu de OneWayToSource sur ma cible TextBox, cela fonctionne correctement. – Bill

Questions connexes