Каким должен быть параметр конвертера для этой привязки - PullRequest
11 голосов
/ 18 декабря 2008

Я пытаюсь реализовать пользовательский элемент управления wpf, который привязывает текстовое поле к списку двойников с помощью конвертера. Как я могу установить экземпляр пользовательского контроля в качестве параметра конвертера?

код для управления показан ниже

Спасибо

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

Ответы [ 4 ]

11 голосов
/ 16 ноября 2011

Другой способ - заставить ваш конвертер наследовать от DependencyObject (или FrameworkElement). Это позволяет вам объявлять свойства зависимостей, позволяя устанавливать его значения из XAML, даже Binding.

Пример: преобразователь для умножения значения, определяющего коэффициент, который получается из свойства (FactorValue) в пользовательском элементе управления (MyControl).

Конвертер:

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
}

Использование в XAML:

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

Итак, теперь вы можете объявить свойство зависимости для каждого параметра, которое вам нужно в конвертере, и связать его.

8 голосов
/ 18 декабря 2008

Параметры для констант, необходимых вашему конвертеру. Чтобы предоставить экземпляр объекта вашему конвертеру, вы можете использовать MultiBinding.

Примечание. Чтобы это решение работало, вам также необходимо изменить конвертер для реализации IMultiValueConverter вместо IValueConverter. К счастью, внесенных изменений довольно мало. Вы можете добавить проверку количества значений, предоставленных вашему конвертеру, 2 в вашем случае.

<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>
1 голос
/ 22 сентября 2010

У меня была такая же проблема, но я не могу использовать MultiBindings, так как мне нужно правильно реализовать метод ConvertBack. Вот решение, которое я реализовал для свойства IsChecked CheckBox:

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

Я не очень знаком с TemplateBindings (или что-нибудь в этом роде с WPF), так что, возможно, это работает только потому, что мой CheckBox находится в DataTemplate ...

1 голос
/ 18 декабря 2008

Я бы назвал элемент управления и затем связал, используя 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>

Нет, подождите, это не сработает, потому что ConverterParameter не является свойством зависимости, а Binding не является объектом DependencyObject. Расширение разметки ReleativeSource должно делать то, что вы хотите, хотя я не использовал его, вложенное в другое MarkupExtension - возможно, в этом случае оно ведет себя не так:

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