it-swarm.com.de

Binden Sie ein Element an zwei Quellen

Ich habe derzeit zwei Textfelder, die eine beliebige Anzahl akzeptieren. Ich habe einen Textblock, der die beiden eingegebenen Zahlen übernimmt und den Durchschnitt berechnet. 

Ich fragte mich, ob es eine Möglichkeit gab, diesen Textblock an beide Textfelder zu binden und einen benutzerdefinierten Konverter zu verwenden, um den Durchschnitt zu berechnen. Ich fange gerade den Text, der Ereignisse in beiden Textfeldern geändert hat, und berechnet den Durchschnitt auf diese Weise, aber ich gehe davon aus, dass die Datenbindung effizienter und einfacher wäre.

37
Nick

Sie suchen nach MultiBinding .

Ihre XAML sieht ungefähr so ​​aus:

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

Mit sinnvollen Ersatz für myConverter, myFirst.Value und mySecond.Value.

55
Jacob Carpenter

Erstellen Sie einen Konverter, der IMultiValueConverter implementiert. Es könnte ungefähr so ​​aussehen:

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
}

Ein mehrwertiger Konverter empfängt ein Objektarray, eines für jede der Bindungen. Sie können diese beliebig verarbeiten, je nachdem, ob Sie es für double oder int oder was auch immer beabsichtigen.

Wenn die beiden Textfelder datengebunden sind, können Sie dieselben Bindungen in der Multibinding für Ihren Textblock verwenden (denken Sie daran, zu benachrichtigen, wenn sich die Eigenschaft ändert, sodass der Durchschnitt aktualisiert wird), oder Sie können den Textwert abrufen, indem Sie über ElementName auf die Textfelder verweisen.

<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>
35
Donnelle

Oder Sie könnten eine Eigenschaft im Code hinterher machen und den TextBlock daran binden ... Ich mache das ständig, und es ist etwas einfacher, als einen Konverter zu erstellen und dann denselben Code dort auszuführen.

Beispiel: (in Ihrem Code hinter dem XAML):

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

Und dann in deiner XAML:

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

Das ist viel einfacher als ein benutzerdefinierter Konverter.

2
Timothy Khouri

Fügen Sie einfach ein schrittweises Verfahren zu Timothys Antwort hinzu:

  1. Richten Sie die View.TextBlock.Text-Eigenschaft ein, um eine Bindung an die ViewModel.AvgValue-Eigenschaft herzustellen.
  2. Fangen Sie das TextChanged-Ereignis des TextBox-Steuerelements ab, und legen Sie dann AvgValue im Handler dieses TextChanged-Ereignisses fest.
  3. Stellen Sie als Teil dieses Handlers in Schritt 2 sicher, dass eine Eigenschaftsänderung ausgelöst wird, damit der TextBlock aktualisiert wird.
0
Michael Nguyen