O que o parâmetro do conversor deve ser para essa ligação
Pergunta
Eu estou tentando implementar um controle de usuário WPF que se liga uma caixa de texto a uma lista de duplas usando um conversor. Como posso definir a instância do controle de usuário para ser o parâmetro conversor?
o código de controlo é mostrado abaixo
Graças
<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>
Solução
Os parâmetros são para constantes necessário para o seu conversor. Para fornecer uma instância de objeto para o seu conversor, você pode usar MultiBinding.
Nota: Para esta solução para o trabalho, você também precisa modificar seu conversor para implementar IMultiValueConverter vez de IValueConverter. Felizmente, as modificações envolvidas são bastante pouco. Você pode adicionar uma validação para o número de valores fornecidos para o seu conversor, 2 no seu 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>
Outras dicas
Outra maneira é fazer o seu herdar conversor de DependencyObject (ou FrameworkElement). Isso permite que você declare propriedades de dependência, tornando possível para definir seus valores de XAML, mesmo uma ligação.
Exemplo:. Um conversor de multiplicar um valor especificando o factor, que é obtido a partir de um alojamento (FactorValue) em um controle personalizado (MyControl)
O conversor:
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
}
Use em XAML:
<MyConverter x:Key="MyConv"
Factor={Binding ElementName=MyControl, Path=FactorValue}
/>
Então, agora você pode declarar uma propriedade de dependência para cada parâmetro que você precisa em seu conversor e vinculá-lo.
Gostaria de citar o controle e, em seguida, ligam 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>
Não, espera, que não vai funcionar porque o ConverterParameter não é uma propriedade de dependência, nem é a ligação de um DependencyObject. extensão Um ReleativeSource marcação deve fazer o que quiser, embora eu não usei-o aninhado dentro de outro MarkupExtension - Talvez não seja bem comportado neste caso:
<TextBox Name="Textbox_baysizes"
Text="{Binding RelativeSource={RelativeSource self},
Path=Parent.Parent.BaySizeItemsSource,
Converter={StaticResource BaySizeConverter,
ConverterParameter={RelativeSource self} }}"
/>
Eu tive o mesmo problema, mas eu não posso usar MultiBindings desde que eu preciso para implementar corretamente o método ConvertBack. Aqui está a solução acabei implementação para a propriedade IsChecked de um CheckBox:
<CheckBox>
<CheckBox.IsChecked>
<Binding Converter="{StaticResource myConverter}" Path="Value">
<Binding.ConverterParameter>
<FrameworkElement DataContext="{TemplateBinding DataContext}" />
</Binding.ConverterParameter>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
Eu não estou super familiarizado com TemplateBindings (ou WPF qualquer coisa para que o assunto), então talvez isso só funciona porque a minha caixa de seleção está em um DataTemplate ...