2010-02-16 3 views
2

J'ai un TreeView imbriqué où je lie l'événement doubleclick sur chaque élément de sorte que le texte du nœud est modifié en une zone de texte modifiable. J'utilise ensuite le gestionnaire d'événements lostFocus pour supprimer la zone de texte et restaurer le texte.WPF Lostfocus ne se déclenche pas correctement vs2010 treeviewitem

void treeViewItemWithMenu_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
    { 
     if (selected == e.Source) 
     { 
      TextBox tb = new TextBox(); 
      tb.Text = this.Header.ToString(); 
      tb.Focus(); 
      tb.LostFocus += new RoutedEventHandler(tb_LostFocus); 
      this.Header = tb; 
      var a = e.OriginalSource; 
      e.Handled = true; 
     } 
    } 


    void tb_LostFocus(object sender, RoutedEventArgs e) 
    { 
     this.Header = ((TextBox)(this.Header)).Text; 
    } 

Malheureusement, il ne semble pas que l'événement lostFocus fonctionne correctement. Lorsque je clique en dehors de la zone de texte, elle ne se déclenche pas du tout. Je peux même doublecliquer sur un autre noeud et il passe en mode édition (c'est-à-dire devient une zone de texte) alors que la première zone de texte semble toujours avoir le focus. La mise au point perdue ne se déclenche pas jusqu'à ce que je commence à aller et venir entre deux zones de texte. J'utilise vs2010 rc avec projet défini sur .net 3.5.

Répondre

2

Oh mon dieu! Pardonnez-moi de le dire, mais chaque utilisateur régulier de WPF qui a lu votre question a probablement hoché sa tête de pitié. Nous sommes tristes pour vous parce que vous n'avez pas encore appris le vrai "Zen de WPF", qui utilise la liaison de données, les modèles et les déclencheurs pour rendre votre interface utilisateur dynamique plutôt que de la faire à l'ancienne. WPF est magnifique à cause de cette capacité. Cela rend également les choses "1000%" plus faciles.

Je vous recommande de changer votre interface utilisateur pour utiliser un déclencheur sur votre TreeViewItem pour remplacer votre HeaderTemplate basé sur une propriété que vous définissez dans le TreeViewItem. Définissez cette propriété true lorsque vous double-cliquez sur l'élément. Définissez false lorsque IsKeyboardFocusWithin devient false (vous pouvez remplacer les métadonnées et ajouter un PropertyChangedCallback pour cela).

En ce qui concerne votre problème LostFocus, je suppose que votre problème est que vous avez plusieurs champs de focalisation ou que c'est un bug dans la RC. Sans voir votre XAML je ne peux pas dire beaucoup plus que cela.

Des détails supplémentaires sur le faire la « voie WPF »

Voici quelques-uns des détails sur la façon de mettre en œuvre cette propriété en utilisant un joint, les déclencheurs et les modèles.

Vos modèles peuvent être aussi simples ou complexes que vous le souhaitez. Voilà simple:

<DataTemplate x:Key="NormalTemplate"> 
    <ContentPresenter /> 
</DataTemplate> 

<DataTemplate x:Key="TextBoxTemplate"> 
    <TextBox Text="{Binding}" /> 
</DataTemplate> 

Voici ce que votre style ressemblerait à ceci:

<Style TargetType="TreeViewItem"> 
    <Setter Property="HeaderTemplate" Value="{StaticResource NormalTemplate}" /> 
    <Trigger Property="local:MyWindowClass.ShowTextBox" Value="true"> 
    <Setter Property="HeaderTemplate" Value="{StaticResource TextBoxTemplate}" /> 
    </Trigger> 
</Style> 

peut créer la propriété attachée "de ShowTextBox" dans MyWindowClass en utilisant l'extrait "propa" - il suffit de taper "PROPA" et cliquez sur l'onglet, puis remplissez les espaces.

Pour passer l'élément pour afficher la zone de texte, juste:

SetShowTextBox(item, true); 

Pour rétablissez:

SetShowTextBox(item, false); 

J'espère que cela aide.

+0

Je crois que IsKeyboardFocusWithin n'est pas assez bon. Quand je clique dehors je ne pense pas que je change la focalisation du clavier. Je pense peut-être que j'ai besoin de trapper l'événement mouseDown dans la fenêtre principale, puis si la cible n'est pas ma zone de texte, perdre le focus. Cela ne gère pas les événements de clavier comme "tab", donc j'espérais un événement "lostFocus" qui l'a fait. btw: la liaison de données lors de l'utilisation d'une table avec une relation interne parent enfant semble plus compliquée, mais j'aimerais un pointeur vers un howto/tutorial. – devzero

+0

Je ne suis pas familier avec ce qui est là-bas tutoriel-sage, mais dans ce cas, vous devez faire presque exactement ce que j'ai dit et pas plus: C'est très simple. J'ajouterai un peu plus à la réponse pour clarifier les détails. DataBinding à une table avec une relation parent-enfant interne n'est pas difficile non plus: Ajoutez simplement une propriété à votre modèle de données (ou au modèle de vue) qui trouve et renvoie la liste des objets enfants et s'y lie dans votre 'HierarchicalDataTemplate'' Propriété ItemsSource'. –

Questions connexes