38 votes

Lier un élément à deux sources

J'ai actuellement deux zones de texte qui acceptent n'importe quel nombre. J'ai un bloc texte qui prend les deux nombres entrés et calcule la moyenne.

Je me demandais s'il était possible de lier ce bloc de texte aux deux zones de texte et d'utiliser un convertisseur personnalisé pour calculer la moyenne ? Actuellement, je capte les événements de changement de texte sur les deux zones de texte et je calcule la moyenne de cette façon, mais je suppose que la liaison de données serait plus efficace et plus facile.

56voto

Jacob Carpenter Points 3225

Vous êtes à la recherche de MultiBinding .

Votre XAML ressemblera à quelque chose comme ça :

<TextBlock>
  <TextBlock.Text>
    <MultiBinding Converter="{StaticResource myConverter}">
      <Binding Path="myFirst.Value" />
      <Binding Path="mySecond.Value" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Avec des remplacements raisonnables pour myConverter , myFirst.Value y mySecond.Value .

36voto

Donnelle Points 3285

Créez un convertisseur qui implémente IMultiValueConverter. Cela pourrait ressembler à quelque chose comme ceci :

class AverageConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int total = 0;
        int number = 0;
        foreach (object o in values)
        {
            int i;
            bool parsed = int.TryParse(o.ToString(), out i);
            if (parsed)
            {
                total += i;
                number++;
            }
        }
        if (number == 0) return 0;
        return (total/number).ToString();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

Un convertisseur multivalue reçoit un tableau d'objets, un pour chacune des liaisons. Vous pouvez traiter ces objets de la manière dont vous le souhaitez, selon qu'il s'agit d'un double, d'un int ou autre.

Si les deux zones de texte sont liées à des données, vous pouvez utiliser les mêmes liaisons dans la liaison multiple pour votre bloc de texte (en n'oubliant pas d'avertir lorsque la propriété change afin que votre moyenne soit mise à jour), ou vous pouvez obtenir la valeur du texte en faisant référence aux zones de texte par ElementName.

<TextBox Text="{Binding Value1}" x:Name="TextBox1" />
<TextBox Text="{Binding Value2}" x:Name="TextBox2" />

<TextBlock>
   <TextBlock.Text>
      <MultiBinding Converter="{StaticResource AverageConverter}">
         <Binding ElementName="TextBox1" Path="Text" />
         <Binding ElementName="TextBox2" Path="Text" />
         <!--  OR  -->
         <!-- <Binding Path="Value1" />  -->
         <!-- <Binding Path="Value2" />  -->

      </MultiBinding>
   </TextBlock.Text>
</TextBlock>

2voto

Timothy Khouri Points 14640

Ou bien, vous pourriez créer une propriété dans le code derrière, et lier le bloc de texte à cette propriété ... Je fais cela tout le temps, et c'est un peu plus simple que de créer un convertisseur, puis de faire le même code ici.

Exemple : (dans votre code derrière le xaml) :

public double AvgValue
{
    get { return (valueA + valueB) / 2.0; }
}

Et ensuite, dans votre XAML :

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AvgValue}" />

C'est BEAUCOUP plus simple qu'un convertisseur personnalisé.

0voto

Michael Nguyen Points 31

Juste pour ajouter une procédure étape par étape à la réponse de Timothy :

  1. Configurez la propriété View.TextBlock.Text pour la lier à la propriété ViewModel.AvgValue.
  2. Attrapez l'événement TextChanged du contrôle TextBox, puis définissez la AvgValue dans le gestionnaire de cet événement TextChanged.
  3. Dans le cadre du gestionnaire de l'étape 2, assurez-vous de déclencher un changement de propriété afin que le bloc de texte soit mis à jour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X