.net - ¿Cuál debería ser el parámetro del convertidor para este enlace?
converters wpf (4)
Estoy tratando de implementar un control de usuario wpf que vincula un cuadro de texto a una lista de dobles mediante un convertidor. ¿Cómo puedo configurar la instancia de control de usuario para que sea el parámetro del convertidor?
el código para el control se muestra a continuación
Gracias
<UserControl x:Class="BaySizeControl.BaySizeTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BaySizeControl"
>
<UserControl.Resources>
<local:BayListtoStringConverter x:Key="BaySizeConverter"/>
</UserControl.Resources>
<Grid>
<TextBox Name="Textbox_baysizes"
Text="{Binding RelativeSource={RelativeSource self},
Path=Parent.Parent.BaySizeItemsSource,
Converter={StaticResource BaySizeConverter}}"
/>
</Grid>
</UserControl>
Otra forma es hacer que su convertidor herede de DependencyObject (o FrameworkElement). Esto le permite declarar propiedades de dependencia, lo que permite establecer sus valores de XAML, incluso un enlace.
Ejemplo: un convertidor para multiplicar un valor que especifica el factor, que se obtiene de una propiedad (FactorValue) en un control personalizado (MyControl).
El convertidor:
public class MyConverter : DependencyObject, IValueConverter
{
// The property used as a parameter
public double Factor
{
get { return (double) GetValue(FactorProperty); }
set { SetValue(FactorProperty, value); }
}
// The dependency property to allow the property to be used from XAML.
public static readonly DependencyProperty FactorProperty =
DependencyProperty.Register(
"Factor",
typeof(double),
typeof(MyConverter),
new PropertyMetadata(1.15d));
#region IValueConverter Members
object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Use the property in the Convert method instead of "parameter"
return (double) value * Factor;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Uso en XAML:
<MyConverter x:Key="MyConv"
Factor={Binding ElementName=MyControl, Path=FactorValue}
/>
Entonces, ahora puede declarar una propiedad de dependencia para cada parámetro que necesita en su convertidor y vincularlo.
Los parámetros son para las constantes que necesita tu convertidor. Para proporcionar una instancia de objeto a su convertidor, puede usar MultiBinding.
Nota: Para que esta solución funcione, también necesita modificar su convertidor para implementar IMultiValueConverter en lugar de IValueConverter. Afortunadamente, las modificaciones involucradas son bastante pequeñas. Puede agregar una validación para la cantidad de valores proporcionados a su convertidor, 2 en su caso.
<TextBox Name="Textbox_baysizes">
<TextBox.Text>
<MultiBinding Converter="{StaticResource BaySizeConverter}">
<Binding RelativeSource="{RelativeSource self}" Path="Parent.Parent.BaySizeItemsSource"/>
<Binding ElementName="Textbox_baysizes"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
Yo nombraría el control y luego uniría usando ElementName:
<UserControl x:Class="BaySizeControl.BaySizeTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BaySizeControl"
Name="Foobar"
>
<UserControl.Resources>
<local:BayListtoStringConverter x:Key="BaySizeConverter"/>
</UserControl.Resources>
<Grid>
<TextBox Name="Textbox_baysizes"
Text="{Binding RelativeSource={RelativeSource self},
Path=Parent.Parent.BaySizeItemsSource,
Converter={StaticResource BaySizeConverter,
ConverterParameter={Binding ElementName=Foobar} }}"
/>
</Grid>
</UserControl>
No, espera, eso no funcionará porque ConverterParameter no es una Propiedad de Dependencia, ni el Binding es DependencyObject. Una extensión de marcado ReleativeSource debe hacer lo que quiera, aunque no lo he usado anidado dentro de otra MarkupExtension; tal vez no se comporte bien en este caso:
<TextBox Name="Textbox_baysizes"
Text="{Binding RelativeSource={RelativeSource self},
Path=Parent.Parent.BaySizeItemsSource,
Converter={StaticResource BaySizeConverter,
ConverterParameter={RelativeSource self} }}"
/>
Tuve el mismo problema, pero no puedo usar MultiBindings ya que necesito implementar correctamente el método ConvertBack. Aquí está la solución que terminé implementando para una propiedad IsChecked de CheckBox:
<CheckBox>
<CheckBox.IsChecked>
<Binding Converter="{StaticResource myConverter}" Path="Value">
<Binding.ConverterParameter>
<FrameworkElement DataContext="{TemplateBinding DataContext}" />
</Binding.ConverterParameter>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
No estoy muy familiarizado con TemplateBindings (o cualquier WPF para el caso), así que tal vez esto solo funciona porque mi CheckBox está en una plantilla de datos ...