que property data context wpf binding

wpf - property - Enlazar un elemento a dos fuentes



wpf set binding (4)

Actualmente tengo dos cuadros de texto que aceptan cualquier número. Tengo un bloque de texto que toma los dos números ingresados ​​y calcula el promedio.

Me preguntaba si había alguna forma de vincular este bloque de texto a ambos cuadros de texto y utilizar un convertidor personalizado para calcular el promedio. Actualmente estoy captando los eventos de texto modificado en ambos cuadros de texto y calculando el promedio de esa manera, pero estoy bajo la suposición de que el enlace de datos sería más eficiente y más fácil.


Cree un convertidor que implemente IMultiValueConverter. Puede parecerse a esto:

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 convertidor multivalor recibe una matriz de objetos, uno para cada uno de los enlaces. Puede procesarlos de la forma que necesite, dependiendo de si tiene la intención de duplicarlo o int o lo que sea.

Si los dos cuadros de texto están enlazados por datos, puede usar los mismos enlaces en el multibinding para su bloque de texto (recordando notificar cuando la propiedad cambia para que se actualice su promedio), o puede obtener el valor del texto refiriéndose a los cuadros de texto por 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>


O bien, podría hacer una propiedad en el código y vincular el TextBlock a eso ... Lo hago todo el tiempo, y es un poco más simple que hacer un convertidor, y luego hacer el mismo código allí.

Ejemplo: (en tu código detrás de xaml):

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

Y luego, en tu XAML:

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

Eso es MUCHO más simple que un convertidor personalizado.


Solo para agregar un procedimiento paso a paso a la respuesta de Timothy:

  1. Configure la propiedad View.TextBlock.Text para enlazar a la propiedad ViewModel.AvgValue.
  2. Capture el evento TextChanged del control TextBox, luego configure AvgValue en el controlador de ese evento TextChanged.
  3. Como parte de ese controlador en el paso 2, asegúrese de generar un cambio de propiedad para que TextBlock se actualice.

Está buscando MultiBinding .

Tu XAML se verá más o menos así:

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

Con reemplazos razonables para myConverter , myFirst.Value y mySecond.Value .