Domanda

Sto cercando di implementare un controllo utente WPF che lega una casella di testo a un elenco dei doppi utilizzando un convertitore. Come posso impostare l'istanza di controllo utente di essere il parametro di convertitore?

il codice per il controllo è mostrato di seguito

Grazie

<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>
È stato utile?

Soluzione

I parametri sono per le costanti necessari al convertitore. Per fornire un'istanza di oggetto per il convertitore, è possibile utilizzare MultiBinding.

Nota: Per questa soluzione funzioni, è anche necessario modificare il convertitore per implementare IMultiValueConverter invece di IValueConverter. Per fortuna, le modifiche in questione sono abbastanza poco. Sarà possibile aggiungere una convalida per il numero di valori previsto per il convertitore, 2 nel tuo 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>

Altri suggerimenti

Un altro modo è rendere il vostro ereditare convertitore da DependencyObject (o FrameworkElement). Questo consente di dichiarare proprietà di dipendenza, rendendo possibile impostare i propri valori dalla XAML, anche un Binding.

Esempio: Un convertitore per moltiplicare un valore specificando il fattore, che si ottiene da una struttura (FactorValue) in un controllo personalizzato (MyControl)

.

Il convertitore:

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
}

Usa in XAML:

<MyConverter x:Key="MyConv"
             Factor={Binding ElementName=MyControl, Path=FactorValue}
/>

Quindi, ora è possibile dichiarare una proprietà di dipendenza per ogni parametro è necessario il convertitore e associarlo.

Vorrei un nome al controllo e quindi associare con 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, aspetta, che non funziona perché il ConverterParameter non è una proprietà di dipendenza, né l'Associazione di un DependencyObject. Un'estensione ReleativeSource markup dovrebbe fare quello che vuoi, anche se non ho usato annidato all'interno di altre MarkupExtension - forse non è ben comportata in questo caso:

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

Ho avuto lo stesso problema, ma non posso usare MultiBindings da quando ho bisogno di attuare correttamente il metodo di ConvertBack. Ecco la soluzione che ho finito per attuare per la proprietà IsChecked di un CheckBox:

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

Io non sono super familiarità con TemplateBindings (o qualsiasi WPF è per questo), quindi forse questo funziona solo perché il mio CheckBox è in un DataTemplate ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top