2008-12-18 15 views
10

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?¿Cuál debe ser el parámetro del convertidor para este enlace

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> 

Respuesta

8

Los parámetros son constantes para los necesitados por su 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> 
+2

Por supuesto, puede pasar la referencia del objeto como parámetros del convertidor, es cierto que debe considerarse una constante ya que WPF no ofrece ninguna forma de volver a vincular el parámetro del convertidor una vez configurado, pero eso no significa que pueda ' t ser una referencia de objeto! –

+0

@Frederic: aparece un error al intentar este código. "Property 'Converter' no admite valores del tipo 'BaySizeControl.BayListtoStringConverter'". ¿Necesitará mi conversor alguna modificación para trabajar con esta solución? –

+0

@ Daniel Paull: Parece que podría funcionar. ¿Podrías por favor dar más detalles sobre esto?gracias –

1

que nombraría el control y luego enlazar mediante 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, que no funciona porque el ConverterParameter no es una propiedad de dependencia, ni es la unión DependencyObject. Una extensión ReleativeSource marcado debe hacer lo que quiera, aunque no he utilizado anidada dentro de otra MarkupExtension - tal vez no se comporta bien en este caso:

<TextBox Name="Textbox_baysizes" 
         Text="{Binding RelativeSource={RelativeSource self}, 
            Path=Parent.Parent.BaySizeItemsSource, 
            Converter={StaticResource BaySizeConverter, 
            ConverterParameter={RelativeSource self} }}" 
         /> 
+0

Ya he probado este método. El parámetro que se pasa es del tipo System.Windows.Data.RelativeSource. No BaySizeTextBox como se esperaba. –

+0

No buscamos "sí mismo", pruebe "{RelativeSource FindAncestor, AncestorType = {x: Type UserControl}}". –

1

que tenían el mismo problema, pero no puedo use MultiBindings ya que necesito implementar correctamente el método ConvertBack. Aquí está la solución que terminé la implementación de la propiedad IsChecked una casilla:

<CheckBox> 
    <CheckBox.IsChecked> 
     <Binding Converter="{StaticResource myConverter}" Path="Value"> 
      <Binding.ConverterParameter> 
       <FrameworkElement DataContext="{TemplateBinding DataContext}" /> 
      </Binding.ConverterParameter> 
     </Binding> 
    </CheckBox.IsChecked> 
</CheckBox> 

No soy muy familiarizados con TemplateBindings (o cualquier WPF para el caso), así que tal vez esto sólo funciona porque mi CheckBox está en una DataTemplate ...

+0

Después de todo, será con un contexto de datos nulo. – Evgeny

11

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} 
/> 

Por lo tanto, ahora se puede declarar una propiedad de dependencia para cada parámetro que necesita en su convertidor y enlazarlo.

Cuestiones relacionadas