2010-09-07 5 views
0
<RichTextBox x:Name="OrigText" Margin="0,0,8,0" d:LayoutOverrides="Width"/> 
    <Button x:Name="OrigFileBrowse" Command="{Binding BrowseCommand}" CommandParameter="{Binding ElementName=OrigText, Path=Document}" HorizontalAlignment="Center" Margin="0,0,8,2.442" Width="75" Content="Browse" Grid.Row="1" d:LayoutOverrides="Height"/> 
    <RichTextBox x:Name="ModifiedText" Grid.Column="1" Margin="8,0,0,0"/> 
    <Button x:Name="ModifiedFileBrowse" Command="{Binding BrowseCommand}" CommandParameter="{Binding ElementName=ModifiedText, Path=Document}" HorizontalAlignment="Center" Width="75" Content="Browse" Grid.Row="1" Grid.Column="1" Margin="0,0,0,2.442" d:LayoutOverrides="Height"/> 
    <Button x:Name="Compare" Command="{Binding CompareCommand}" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Content="Compare" Grid.Row="2" Grid.ColumnSpan="2"> 
     <Button.CommandParameter> 
      <x:Array Type="RichTextBox"> 
       <local:CompareTextView/> 
      </x:Array> 
     </Button.CommandParameter> 
    </Button> 

Essayer d'obtenir 2 articles à passer lorsque le bouton est cliqué Comparer car il sera alors exécuter une commande comparer. Tenté de faire usage de MultiBinding cependant qui tire sur l'instanciation et donc le convertisseur se déclenche alors en conséquence. Il ne se déclenche pas lorsque je clique sur comparer et la commande de comparaison est exécutée.contrôle de référence XAML et propriétés dans x: Array

Avec cela qui ne fonctionne pas, j'essaie maintenant de référencer les contrôles dans XAML pour passer à l'intérieur d'une ArrayExtension. Pas sûr de la syntaxe ou si c'est même possible car je sais que vous ne pouvez pas lier dans ArrayExtension. Le ci-dessus échoue, car il ne peut pas construire une nouvelle vue CompareTextView, qui n'a pas de constructeur par défaut depuis que je me sers de Prism ...

assez frustrant, nous espérons que quelqu'un peut me aider ...

EDIT :

Vous voulez effacer certaines choses. Le problème n'est pas que je veux que CanExecute soit appelé à nouveau. Le problème est que lors de l'instanciation des contrôles, le convertisseur est appelé et exécuté et les valeurs sont retournées ... mais où vont-ils je n'ai aucune idée? Le convertisseur n'est jamais appelé à nouveau. Si je pouvais obtenir les références initiales au FlowDocument, tout cela serait un point discutable ... mais cela ne retourne rien en soi ... puisqu'il s'agit d'une commande ... si cela a du sens ... utilisation de MultiBinding.

 <Button x:Name="Compare" Command="{Binding CompareCommand}" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Content="Compare" Grid.Row="2" Grid.ColumnSpan="2"> 
     <Button.CommandParameter> 
      <MultiBinding Converter="{StaticResource FlowDocumentConverter}"> 
       <Binding ElementName="OrigText" Path="Document"/> 
       <Binding ElementName="ModifiedText" Path="Document"/> 
      </MultiBinding> 
     </Button.CommandParameter> 
    </Button> 

MISE À JOUR:

Essayé ce que refereejoe mentionne here, faites défiler vers le bas un peu pour voir son affectation. Bien que CanExecute se déclenche continuellement, cela ne résout pas le problème. En outre, j'ai changé le MultiBinding pour être un seul élément, il revient null. Encore une fois, lorsque les feux de conversion sur instanciation les références FlowDocument sont là ...

RÉPONSE:

mention Abe qu'il était mis en mémoire cache m'a amené à essayer autre chose. Comme je savais que les références de FlowDocument étaient disponibles lorsque le convertisseur était appelé, je savais qu'ils étaient là. Quelque chose devenait encrassé. La pièce maîtresse semble être dans le convertisseur lui-même. Je retournais simplement l'objet []. Ensuite, lorsque la commande a déclenché l'argument était en effet un objet [] mais les deux éléments étaient nuls. J'ai créé une classe appelée Docs, qui possédait deux propriétés, une pour chaque référence FlowDocument. Lorsque le convertisseur a été déclenché, j'ai défini les propriétés de manière appropriée, puis j'ai renvoyé l'objet Docs. Maintenant, quand j'ai lancé la commande de comparaison, l'objet Docs était l'args et il avait la référence à la FlowDocuments juste comme j'avais besoin! Je ne sais pas si c'est par conception, mais le fait que les éléments soient perdus lors de l'utilisation de l'objet [] n'a aucun sens pour moi.

Répondre

2

La bonne façon de le faire est en effet avec un MultiBinding sur le CommandParameter. Vous ne le verrez pas appeler votre méthode CanExecute sauf si WPF est informé que la méthode peut renvoyer une valeur différente de celle déjà mise en cache (via l'événement CanExecuteChanged).

Puisque vous vous basez sur le paramètre transmis pour le déterminer, nous devons augmenter l'événement lorsque le paramètre change. Puisque nous ne pouvons pas vraiment déterminer cela dans la commande, nous pouvons utiliser une autre technique: dites à WPF d'interroger notre commande à chaque fois qu'elle interroge UICommands.Cela se fait en mettant en œuvre votre ICommand comme ceci:

public class MyCommand : ICommand 
{ 
    public void Execute(object parameter) { /* do stuff */ } 
    public bool CanExecute(object parameter { /* determine if we can do stuff */ } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 
} 

De toute évidence, cela vous empêche d'utiliser le prisme DelegateCommand, mais cela répondra aux changements des paramètres de commande.

MISE À JOUR

Une autre chose à considérer est que la propriété Document sur le RichTextBox ne change pas réellement. Au lieu de cela, lorsque vous tapez, le contenu des modifications FlowDocument. Comme les instances de propriété ne changent pas, le convertisseur ne sera plus renvoyé et la valeur initialement convertie sera stockée dans la propriété CommandParameter.

L'un des moyens pour forcer le convertisseur à être appelé à nouveau est d'ajouter un Binding au MultiBinding qui est lié à une propriété qui va modifier chaque fois que le texte des RichTextBox changements.

Une solution peu hacky serait d'utiliser la propriété IsKeyboardFocusWithin, comme qui imitent le comportement de liaison par défaut de TextBox.Text (lorsque la TextBox désélectionné, les Binding mises à jour):

<MultiBinding Converter="{StaticResource FlowDocumentConverter}"> 
    <Binding ElementName="OrigText" Path="Document" /> 
    <Binding ElementName="ModifiedText" Path="Document" /> 
    <Binding ElementName="OrigText" Path="IsKeyboardFocusWithin" /> 
    <Binding ElementName="ModifiedText" Path="IsKeyboardFocusWithin" /> 
</MultiBinding> 

Il est évident que, dans votre convertisseur, vous devrez ignorer ces valeurs supplémentaires, car elles ne sont pas pertinentes pour votre conversion.

+0

Abe, merci pour les commentaires ... de même qu'une DelegateCommand via Prism n'est pas possible? –

+0

Ajout d'une édition en haut pour effacer certaines choses ... –

+0

Mon exemple d'application utilisait à l'origine TextBox, car le convertisseur était plus facile à écrire. J'ai mis à jour ma réponse pour résoudre le problème avec RichTextBoxes. –

Questions connexes