Quale dovrebbe essere il parametro convertitore essere per questa associazione
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>
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 ...