2010-06-21 6 views
0

Tout ce que je voulais, c'était des liaisons différentes sur des onglets différents, donc les onglets de commutation bascule la disponibilité de la commande. Je pensais que CommandBindings fonctionnait de cette façon.WPF CommandBinding PAS sur l'élément de niveau supérieur/Window/this

Mais j'ai passé la dernière fois en essayant de faire fonctionner cet exemple simple. Soit je me méprends fondamentalement (et ce ne serait pas une première) ou quelque chose ne va pas.

J'ajoute un CommandBinding à textBoxA mais pas à textBoxB. Les déplacer entre eux devrait activer et désactiver le bouton qui est défini sur la commande correspondante. L'ajout de CommandBinding à la fenêtre active le bouton, mais ce type de bouton tue tout le point de l'objet CommandBindings spécifique aux éléments.

En utilisant cette XAML

<Window x:Class="WpfApplication2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="500"> 
    <Canvas> 
     <Button Canvas.Left="31" Canvas.Top="24" Content="Click Me" Name="button1" Width="100"/> 
     <TextBox Canvas.Left="155" Canvas.Top="22" Height="23" Name="textBoxA" Width="120" Text="A" /> 
     <TextBox Canvas.Left="298" Canvas.Top="22" Height="23" Name="textBoxB" Width="120" Text="B" /> 
    </Canvas> 
</Window> 

En utilisant ce code derrière

public MainWindow() 
{ 
    InitializeComponent(); 

    button1.Command = ApplicationCommands.Open; 

    var _Binding = new CommandBinding(button1.Command); 
    textBoxA.CommandBindings.Add(_Binding); 
    textBoxB.CommandBindings.Clear(); // nothing bound 

    _Binding.CanExecute += (s, e) => 
    { 
     e.CanExecute = true; 
    }; 

    _Binding.Executed += (s, e) => 
    { 
     MessageBox.Show("Hello"); 
    }; 
} 

Vous verrez (si vous essayez ce code) que le bouton reste désactivé, même lorsque vous passez d'une zone de texte à L'autre. (Même si textBoxA doit activer le bouton car il implémente le CommandBinding du bouton).

Comment cela est-il supposé fonctionner?

Merci d'avance.

+0

J'ai essayé de poser cette question: http://stackoverflow.com/questions/3339257/wpf-routed-command-with-bindings -per-tab –

Répondre

0

Je ne vois pas comment cela fonctionnerait et il semble que vous manquiez le point (désolé) - CommandBindings sont censés être appliqués aux éléments parents (le mettre sur le canevas fonctionnera aussi bien). Lorsque le bouton est cliqué, la commande RoutedCommand va «remonter» dans l'arborescence visuelle, ce qui signifie que tous les éléments parents verront leurs événements qui ont été liés à cette commande. La raison pour laquelle le bouton reste désactivé est que vous ne pouvez pas exécuter la commande open à ce stade et que CommandBinding n'est pas évalué car il n'est pas dans le chemin d'exécution. voir ici:

http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.aspx

+0

Si vous regardez ici (http://stackoverflow.com/questions/1375483/wpf-textbox-interceping-routeduicommands), il montre que WPF a des liaisons par défaut pour une zone de texte (et probablement d'autres contrôles).Je sais aussi que le copier/coller (par exemple) est par défaut pour la zone de texte. Pas seulement sur les contrôles parents, tels que le canevas. Pourquoi une zone de texte, par exemple, aurait une propriété de collection CommandBindings si elle ne pouvait pas faire ce que je suggérais. (BTW, merci pour la réponse) Aussi, mettre à Canvas (s'il y en a deux) a le même problème que mon échantillon. –

+0

Autant que je sache, le CommandBinding a pour but de permettre à un élément situé plus haut dans l'arbre d'écouter et de s'exécuter lorsqu'une commande est déclenchée sur un élément plus bas. Les boîtes de texte ont la propriété CommandBindings car il s'agit d'un UIElement et vous pouvez réellement placer un bouton dans une zone de texte sans problème, puis récupérer les événements de commande de boutons. –

0

Je vais essayer de voir si je peux frapper votre scénario:

<Canvas> 
    <Button ... Command="Open"> 
     <CommandBindings> 
      <CommandBinding Command="Open" Executed="OnOpen"/> 
     <CommandBindings> 
    </Button> 
    <TextBox ... > 
     <CommandBindings> 
      <CommandBinding Command="Open" Executed="OnOpen"/> 
     <CommandBindings> 
    </TextBox> 
    <TextBox ... /> 
</Canvas> 

Et dans le code-behind:

private void OnOpen(object sender, ExecutedRoutedEventArgs e) 
{ 
    MessageBox.Show("Hello"); 
} 

L'idée est CommandBindings être un raccourci pour avoir des raccourcis clavier communs à travers les boutons et autres contrôles dans un contexte (typiquement un contrôle userc). Ensuite, chaque région peut avoir des significations différentes pour l'Open-command (l'un ouvrira peut-être un fichier - dans un autre, il ouvrira l'élément sélectionné dans ListView et ainsi de suite).

Dans mon exemple, si vous appuyez sur CTRL + O alors que TextBox A ou le bouton a le focus, le MessageBox 'Hello' est déclenché. Mais lisez la page liée à Leom pour une explication plus approfondie.

+0

Merci. Donc, ma question suivante serait que je veux utiliser la commande Open, mais je veux un CommandBinding (disons, OnOpen1()) quand je suis dans TextBoxA et un CommandBinding différent (disons, OnOpen2()) quand je suis dans TextBoxB. Et, pour faire bonne mesure, je veux que le bouton soit désactivé si je suis dans TextBoxC. Une implémentation directe, comme la vôtre, fonctionne bien. Je le réalise. –

+0

Ensuite, vous venez d'échanger la partie Execute de CommandBinding en question. Donc, un eventhandler pour TextBoxA et un autre pour TextBoxB. Cependant, vous devez supprimer la liaison de commande pour le bouton - alors tout devrait fonctionner comme il répondra au CommandBinding qui est 'le plus proche' dans le VisualTree du focus logique - (reliant TextBoxA si vous êtes dans TextBoxA et TextBoxB si vous êtes là et ainsi de suite). – Goblin

Questions connexes