2014-05-02 7 views
0

J'utilise une propriété jointe pour m'inscrire à l'événement TargetUpdated à partir d'un TextBlock, afin que je puisse être averti chaque fois que le texte change.Événement WPF TargetUpdated ne se déclenche pas sur ContentControl

Utilisation du XAML suivant:

<DataTemplate DataType="{x:Type targetUpdatedApp:Item}"> 
     <targetUpdatedApp:LabelControl Text="{Binding Text, NotifyOnTargetUpdated=True}" Style="{StaticResource LabelTemplateStyle}"/> 
    </DataTemplate> 
</Window.Resources> 

<StackPanel> 
    <ListBox ItemsSource="{Binding Items}"> 
     <!--<ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Text, NotifyOnTargetUpdated=True}" targetUpdatedApp:DesiredWidth.DesiredMinWidth="120"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate>--> 
    </ListBox> 

    <Button Click="ButtonBase_OnClick">Button</Button> 
</StackPanel> 

Voici mon code AttachedProperty:

public class DesiredWidth 
{ 
    public static readonly DependencyProperty DesiredMinWidthProperty = 
     DependencyProperty.RegisterAttached(
      "DesiredMinWidth", typeof (double), 
      typeof (TextBlock), new PropertyMetadata(OnDesiredMinWidthChanged)); 

    public static double GetDesiredMinWidth(DependencyObject obj) 
    { 
     return (double) obj.GetValue(DesiredMinWidthProperty); 
    } 

    public static void SetDesiredMinWidth(DependencyObject obj, double value) 
    { 
     obj.SetValue(DesiredMinWidthProperty, value); 
    } 

    static void OnDesiredMinWidthChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     var textBlock = obj as TextBlock; 
     if (textBlock == null) 
     { 
      return; 
     } 

     if (args.NewValue != null) 
     { 
      textBlock.TargetUpdated += OnTextBoxTargetUpdated;  
     } 
    } 

    static void OnTextBoxTargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e) 
    { 
     if (e.Property == TextBlock.TextProperty) 
     { 

     } 
    } 
} 

La collection Items liée au ListBox est un ObservableCollection et les éléments qui s'y trouvent implémentent INotifyPropertyChanged. Si je décommente le code du ListBox.ItemTemplate et l'utilise à la place du style cela fonctionne bien, mais j'utilise LabelControl (qui a essentiellement un texte DependencyProperty) décrit sur le style l'événement TargetUpdated souscrit sur le AttachedProperty ne se fait jamais virer.

Quelqu'un pourrait-il m'aider à résoudre ce problème? Merci d'avance.

PS: Ajouté de commentaire:

<Style x:Key="LabelTemplateStyle" TargetType="{x:Type argetUpdatedApp:LabelControl}">  
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type targetUpdatedApp:LabelControl}"> 
       <TextBlock Text="{TemplateBinding Text}" TargetUpdatedApp:DesiredWidth.DesiredMinWidth="120"/> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
+0

Ajouté manquant Style:

+0

ce serait mieux si vous, mais ce commentaire dans la question. mieux vaut lire –

Répondre

0

NotifyOnTargetUpdated ne s'appliquera à la liaison qu'elle est activée, non sur les liaisons des éléments contenus dans. Vous avez cet ensemble sur le LabelControl, mais le gestionnaire d'événements est attaché au TextBlock à l'intérieur de son ControlTemplate, qui ne le notifie pas. Utilisation:

<ControlTemplate TargetType="{x:Type targetUpdatedApp:LabelControl}"> 
    <TextBlock Text="{TemplateBinding Text, NotifyOnTargetUpdated=True}" targetUpdatedApp:DesiredWidth.DesiredMinWidth="120"/> 
</ControlTemplate> 

Une autre façon que vous pouvez faire, ce qui ne serait pas vous obliger à modifier les liaisons, est d'utiliser une autre propriété attachée au lieu de l'Text propriété de l'élément:

<TextBlock DesiredWidth.Text="{Binding Text}" DesiredWidth.MinWidth="120" /> 

Et DesiredWidth Vous pouvez ensuite ajouter un rappel OnTextChanged qui transmet la valeur au Text du TextBlock et effectue toute autre manipulation nécessaire.

+0

Merci pour vos commentaires. J'ai essayé la première approche et le code est incapable de compiler, puisque j'utilise un TemplateBinding NotifyOnTargetUpdated n'est pas supporté. Lors de la seconde approche, il lance une exception au démarrage, le type de propriété attaché que je devrais créer serait de BindingExpression au lieu de chaîne. –

+0

@HelderCosta La propriété jointe devrait fonctionner. Assurez-vous de le déclarer correctement. J'ai remarqué dans votre question que vous utilisez 'typeof (TextBlock)' dans votre 'RegistereAttached'. Cela devrait être le type où il est déclaré à la place ('typeof (DesiredWidth)'). – nmclean

Questions connexes