2010-09-28 20 views
2

J'ai une liaison TabControl à certains éléments. En dessous, il y a un bouton où je peux ajouter des éléments de manière dynamique. En ajoutant un élément, le nouvel élément devrait devenir l'onglet actif (fonctionne très bien avec TabControl.SelectedItem):DataContextChanged d'une tabulation dans un TabControl est déclenché trop tôt

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:this="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <TabControl ItemsSource="{Binding Items}" 
        SelectedItem="{Binding SelectedItem, Mode=OneWay}"> 
      <TabControl.ContentTemplate> 
       <DataTemplate> 
        <this:UserControl1 /> 
       </DataTemplate> 
      </TabControl.ContentTemplate> 
     </TabControl> 
     <Button Content="Foo" Click="Button_Click"/> 
    </StackPanel> 
</Window> 

code-behind:

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : INotifyPropertyChanged 
    { 
     public ObservableCollection<Foo> Items { get; set; } 
     public Foo SelectedItem { get { return Items.Last(); } } 
     public event PropertyChangedEventHandler PropertyChanged; 

     public MainWindow() 
     { 
      Items = new ObservableCollection<Foo>(); 
      Items.Add(new Foo {Bar = "bar"}); 

      InitializeComponent(); 
      DataContext = this; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      Items.Add(new Foo {Bar = "bar"}); 

      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("Items")); 
       PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem")); 
      } 
     } 
    } 

    public class Foo { public string Bar { get; set; } } 
} 

Le UserControl1 ressemble à ceci:

<UserControl x:Class="WpfApplication1.UserControl1" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <StackPanel> 
     <TextBox/> 
     <TextBox x:Name="_textBox" 
      DataContextChanged="OnDataContextChanged" 
      Text="{Binding Bar}" /> 
    </StackPanel> 
</UserControl> 

Et le code-behind de celui-ci devrait se concentrer _textBox et sélectionnez Tout son texte lorsque l'utilisateur clique sur l'onglet:

using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class UserControl1 
    { 
     public UserControl1() 
     { 
      InitializeComponent(); 
     } 

     private void OnDataContextChanged(object sender, 
              DependencyPropertyChangedEventArgs e) 
     { 
      _textBox.Focus(); 
      _textBox.SelectAll(); 
     } 
    } 
} 

J'essaie d'atteindre cet objectif avec l'événement DataContextChanged, mais en raison de son imprévisibilité (cf. http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontextchanged.aspx), cela ne fonctionne pas tout le temps. Je l'ai également essayé avec l'événement Loaded, mais celui-ci ne sera appelé qu'une seule fois lors du chargement du DataTemplate. Donc, je pense que je dois recevoir l'événement Loaded chaque fois que le DataContext a changé et que le moteur de liaison de données a terminé son travail. Y a-t-il un tel événement?

Répondre

0

Voulez-vous sélectionner le texte lorsque l'utilisateur ajoute un onglet ET lorsque l'utilisateur clique sur un autre onglet? Si c'est le cas, vous voudrez peut-être gérer cela avec deux gestionnaires d'événements - L'onglet a changé l'événement pour le contrôle de tabulation - et ensuite le définir dans le code lorsque vous ajoutez un nouvel élément.

Le DataContext correspondant à votre code ne change pas. Il est défini sur la fenêtre principale, puis hérité jusqu'aux contrôles enfants.

public MainWindow() 
    { 
     Items = new ObservableCollection<Foo>(); 
     Items.Add(new Foo {Bar = "bar"}); 

     InitializeComponent(); 
     DataContext = this; 
    }