2009-02-11 4 views
1

Je peux déclencher des paramètres de propriété sur mon modèle de ListBoxItem en fonction des propriétés de l'objet de données sous-jacentes à l'aide DataTrigger avec quelque chose comme çaInverse DataTrigger?

<DataTrigger Binding="{Binding Path=IsMouseOver}" Value="true"> 
    <Setter TargetName="ItemText" Property="TextBlock.TextDecorations" Value="Underline"> 
    </Setter> 
</DataTrigger> 

Mais si je veux faire le contraire? Je veux dire définir une valeur de propriété sur l'objet de données sous-jacent en fonction de la valeur de propriété de mon ListBoxItem. Quelque chose comme:

<Trigger Property="IsMouseOver" Value="True"> 
    <Setter Property="MyClass.IsHilited" Value="True"></Setter> 
</Trigger> 

est-il un mécanisme pour quelque chose comme ceci ou quelle serait l'approche recommandée pour faire face à des situations comme celle-ci?

Merci.

+0

J'ai ajouté un exemple de code à ma réponse - cela fonctionne-t-il pour vous? – Andy

+0

Oui, cela fonctionne. Merci! –

Répondre

2

Je pense que vous pouvez utiliser un EventSetter faire en XAML ce que Josh G suggéré dans le code. Peut-être en créer un pour les événements MouseEnter et MouseLeave, et styliser le contrôle de manière appropriée pour chacun?

Mise à jour: Vous pouvez configurer les événements comme celui-ci:

<ListBox> 
    <ListBox.Resources> 
     <Style TargetType="{x:Type ListBoxItem}"> 
      <EventSetter Event="MouseEnter" Handler="OnListBoxItemMouseEnter" /> 
      <EventSetter Event="MouseLeave" Handler="OnListBoxItemMouseLeave" /> 
     </Style> 
    </ListBox.Resources> 
    <ListBoxItem>Item 1</ListBoxItem> 
    <ListBoxItem>Item 2</ListBoxItem> 
    <ListBoxItem>Item 3</ListBoxItem> 
    <ListBoxItem>Item 4</ListBoxItem> 
    <ListBoxItem>Item 5</ListBoxItem> 
</ListBox> 

Les registres de style pour les MouseEnter et MouseLeave événements pour tous ListBoxItems définis dans ce ListBox.

Et puis dans votre code derrière fichier:

private void OnListBoxItemMouseEnter(object sender, RoutedEventArgs e) 
{ 
    ListBoxItem lvi = sender as ListBoxItem; 
    if(null != lvi) 
    { 
     lvi.Foreground = new SolidColorBrush(Colors.Red); 
    } 
} 

private void OnListBoxItemMouseLeave(object sender, RoutedEventArgs e) 
{ 
    ListBoxItem lvi = sender as ListBoxItem; 
    if(null != lvi) 
    { 
     lvi.Foreground = new SolidColorBrush(Colors.Black); 
    } 
} 

Ces Les gestionnaires définissent la couleur du texte du ListBoxItem en rouge lorsque la souris survole l'élément, et reviennent au noir lorsque la souris le quitte.

+0

Oui, j'ai essayé de le faire mais je ne peux pas envelopper la tête autour du problème où placer ces setters (ou comment câbler les événements au bon endroit pour cette question). J'ai besoin MouseEnter/Laisser des événements pour les articles individuels (non la zone de liste) ou je besoin d'un moyen de déterminer l'élément plané à partir du gestionnaire de listbox –

+0

Oui, cela fonctionne. Merci! –

+0

Andy, savez-vous comment faire de même dans le code? Je veux dire que la définition de listBox.AddHandler (ListBoxItem.MouseEnterEvent ...) entraîne le déclenchement de l'événement sur l'ensemble de la légende. Y a-t-il un moyen d'attacher un événement sur tous les articles à la fois ou est-ce que je suis bloqué avec l'itération des éléments et en les définissant un par un? –

1

Les déclencheurs WPF sont destinés à provoquer des changements visuels. Les objets Setter dans les déclencheurs provoquent des changements de propriété sur le contrôle.

Si vous voulez répondre à un événement (comme un EventTrigger), vous pouvez toujours simplement vous abonner à l'événement en code, puis définir la propriété data dans le gestionnaire.

Vous pouvez utiliser MouseEnter et MouseLeave de cette manière. Par exemple:

listBox.MouseEnter += listBox_MouseEnter; 
listBox.MouseLeave += listBox_MouseLeave; 

void listBox_MouseEnter(object sender, MouseEventArgs e) 
{ 
    listBox.MyClass.IsHilited = true; 
} 

void listBox_MouseLeave(object sender, MouseEventArgs e) 
{ 
    listBox.MyClass.IsHilited = false; 
} 

Certaines propriétés sur un contrôle que vous pourriez lier la propriété de l'objet de données, comme ceci:

Binding myBind = new Binding("IsHilited"); 
myBind.Source = listBox.DataContext; 
listBox.SetBinding(listBox.IsEnabled, myBind); 

Vous ne pouvez pas utiliser IsMouseOver dans une liaison cependant,.

Si vous créez un contrôle personnalisé, vous pouvez disposer d'une plus grande flexibilité pour créer une liaison de ce type dans le contrôle. Vous pouvez créer une propriété de dépendance personnalisée et la synchroniser avec la propriété data du gestionnaire DependencyPropertyChanged. Vous pouvez ensuite définir cette propriété de dépendance avec un déclencheur WPF.

Voici un exemple:

public static readonly DependencyProperty IsHilitedProperty = 
    DependencyProperty.Register("IsHilited", typeof(bool), typeof(CustomListBox), 
    new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsHilitedChanged))); 

public double IsHilited 
{ 
    get 
    { 
     return (bool)GetValue(IsHilitedProperty); 
    } 
    set 
    { 
     SetValue(IsHilitedProperty, value); 
    } 
} 


private static void OnIsHilitedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
{ 
    CustomListBox box = obj as CustomListBox; 

    if (box != null) 
     box.MyClass.IsHilited = box.IsHilited; 

    // Or: 
    // Class myClass = box.DataContext as Class; 
    // myClass.IsHilited = box.isHilited; 
} 

<Trigger Property="IsMouseOver" Value="True"> 
    <Setter Property="IsHilited" Value="True"/> 
</Trigger> 
+0

Merci.Mon problème est que je ne peux pas comprendre comment les événements MouseEnter/MouseLeave des éléments enfants du ListBox câbler les gestionnaires d'événements ou de déterminer quel élément est sous le curseur (le cas échéant) dans le haut niveau des événements MouseEnter/MouseLeave de la ListBox? –

+0

Répondre aux événements sur ListBoxItems est un problème différent. Je suggère de créer un modèle d'élément pour les éléments dans le ListBox. Vous pouvez ensuite créer un déclencheur pour IsMouseOver dans ItemTemplate. –