绑定到转换器参数

发布于 2024-10-07 02:53:57 字数 386 浏览 2 评论 0原文

是否可以在 Silverlight 4.0 中绑定到 ConverterParameter?

例如,我想做这样的事情,并将 ConverterParameter 绑定到 ViewModel 中的一个对象。

如果这不可能,还有其他选择吗?

<RadioButton
  Content="{Binding Path=Mode}"
  IsChecked="{Binding
    Converter={StaticResource ParameterModeToBoolConverter},
    ConverterParameter={Binding Path=DataContext.SelectedMode,ElementName=root}}"
/>

Is it possible to bind to a ConverterParameter in Silverlight 4.0?

For instance I would like to do something like this and bind the ConverterParameter to an object in a ViewModel for instance.

If this is not possible are there any other options?

<RadioButton
  Content="{Binding Path=Mode}"
  IsChecked="{Binding
    Converter={StaticResource ParameterModeToBoolConverter},
    ConverterParameter={Binding Path=DataContext.SelectedMode,ElementName=root}}"
/>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

厌味 2024-10-14 02:53:57

不幸的是,不能,您无法绑定到 ConverterParameter。我过去使用过两个选项:不使用转换器,而是在 ViewModel(或您绑定的任何内容)上创建一个属性来为您进行转换。如果您仍然想走转换器路线,请将整个绑定对象传递给转换器,然后您可以这样进行计算。

Unfortunetly no, you can't bind to a ConverterParameter. There's two options I've used in the past: instead of using a Converter, create a property on your ViewModel (or whatever you're binding to) which does the conversion for you. If you still want to go the Converter route, pass the entire bound object to the converter and then you can do your calculation that way.

浅唱々樱花落 2024-10-14 02:53:57

另一种选择是通过创建一个自定义转换器来包装其他转换器并从属性传入转换器参数。只要这个自定义转换器继承了DependencyObject并使用了DependencyProperty,就可以绑定到。例如:

<c:ConverterParamHelper ConverterParam="{Binding ...}">

    <c:ConverterParamHelper.Converter>

        <c:RealConverter/>

    </c:ConverterParamHelper.Converter>

</c:ConverterParamHelper>

Another option is to get fancy by creating a custom converter that wraps your other converter and passes in a converter param from a property. As long as this custom converter inherits DependencyObject and uses a DependencyProperty, it can be bound to. For example:

<c:ConverterParamHelper ConverterParam="{Binding ...}">

    <c:ConverterParamHelper.Converter>

        <c:RealConverter/>

    </c:ConverterParamHelper.Converter>

</c:ConverterParamHelper>
萌酱 2024-10-14 02:53:57

我知道这是一个老问题,但也许这对遇到它的人有用。我找到的解决方案如下:

public class WattHoursConverter : FrameworkElement, IValueConverter
    {

        #region Unit (DependencyProperty)

        /// <summary>
        /// A description of the property.
        /// </summary>
        public string Unit
        {
            get { return (string)GetValue(UnitProperty); }
            set { SetValue(UnitProperty, value); }
        }
        public static readonly DependencyProperty UnitProperty =
            DependencyProperty.Register("Unit", typeof(string), typeof(WattHoursConverter),
            new PropertyMetadata("", new PropertyChangedCallback(OnUnitChanged)));

        private static void OnUnitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((WattHoursConverter)d).OnUnitChanged(e);
        }

        protected virtual void OnUnitChanged(DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion


        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
// you can use the dependency property here
...
}
}

在您的xaml中:

<UserControl.Resources>
    <converters:WattHoursConverter x:Key="WattHoursConverter" Unit="{Binding UnitPropFromDataContext}"/>
 </UserControl.Resources>
....
  <TextBlock Grid.Column="1" TextWrapping="Wrap" Text="{Binding TotalCO2, Converter={StaticResource KgToTonnesConverter}}" FontSize="13.333" />

I know it's an old question but maybe this will be useful to somebody who came across it. The solution I found is as follow:

public class WattHoursConverter : FrameworkElement, IValueConverter
    {

        #region Unit (DependencyProperty)

        /// <summary>
        /// A description of the property.
        /// </summary>
        public string Unit
        {
            get { return (string)GetValue(UnitProperty); }
            set { SetValue(UnitProperty, value); }
        }
        public static readonly DependencyProperty UnitProperty =
            DependencyProperty.Register("Unit", typeof(string), typeof(WattHoursConverter),
            new PropertyMetadata("", new PropertyChangedCallback(OnUnitChanged)));

        private static void OnUnitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((WattHoursConverter)d).OnUnitChanged(e);
        }

        protected virtual void OnUnitChanged(DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion


        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
// you can use the dependency property here
...
}
}

and in your xaml:

<UserControl.Resources>
    <converters:WattHoursConverter x:Key="WattHoursConverter" Unit="{Binding UnitPropFromDataContext}"/>
 </UserControl.Resources>
....
  <TextBlock Grid.Column="1" TextWrapping="Wrap" Text="{Binding TotalCO2, Converter={StaticResource KgToTonnesConverter}}" FontSize="13.333" />
罗罗贝儿 2024-10-14 02:53:57

可以通过创建支持绑定到 ConverterParameter 的自己的 Binding 来实现。以下是如何使用它:

<RadioButton Content="{Binding Path=Mode}" 
    IsChecked="{BindingWithBindableConverterParameter Converter={StaticResource ParameterModeToBoolConverter},
    ConverterParameter={Binding Path=DataContext.SelectedMode,ElementName=root}}" />

以及实现此绑定的代码:

[ContentProperty(nameof(Binding))]
public class BindingWithBindableConverterParameter : MarkupExtension
{
    public Binding Binding { get; set; }
    public BindingMode Mode { get; set; }
    public IValueConverter Converter { get; set; }
    public Binding ConverterParameter { get; set; }

    public BindingWithBindableConverterParameter()
    { }

    public BindingWithBindableConverterParameter(string path)
    {
        Binding = new Binding(path);
    }

    public BindingWithBindableConverterParameter(Binding binding)
    {
        Binding = binding;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var multiBinding = new MultiBinding();
        Binding.Mode = Mode;
        multiBinding.Bindings.Add(Binding);
        if (ConverterParameter != null)
        {
            ConverterParameter.Mode = BindingMode.OneWay;
            multiBinding.Bindings.Add(ConverterParameter);
        }
        var adapter = new MultiValueConverterAdapter
        {
            Converter = Converter
        };
        multiBinding.Converter = adapter;
        return multiBinding.ProvideValue(serviceProvider);
    }

    [ContentProperty(nameof(Converter))]
    private class MultiValueConverterAdapter : IMultiValueConverter
    {
        public IValueConverter Converter { get; set; }

        private object lastParameter;

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (Converter == null) return values[0]; // Required for VS design-time
            if (values.Length > 1) lastParameter = values[1];
            return Converter.Convert(values[0], targetType, lastParameter, culture);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            if (Converter == null) return new object[] { value }; // Required for VS design-time

            return new object[] { Converter.ConvertBack(value, targetTypes[0], lastParameter, culture) };
        }
    }
}

It is possible by creating an own Binding which supports binding to the ConverterParameter. Here is how to use it:

<RadioButton Content="{Binding Path=Mode}" 
    IsChecked="{BindingWithBindableConverterParameter Converter={StaticResource ParameterModeToBoolConverter},
    ConverterParameter={Binding Path=DataContext.SelectedMode,ElementName=root}}" />

And the code with the implementation for this binding:

[ContentProperty(nameof(Binding))]
public class BindingWithBindableConverterParameter : MarkupExtension
{
    public Binding Binding { get; set; }
    public BindingMode Mode { get; set; }
    public IValueConverter Converter { get; set; }
    public Binding ConverterParameter { get; set; }

    public BindingWithBindableConverterParameter()
    { }

    public BindingWithBindableConverterParameter(string path)
    {
        Binding = new Binding(path);
    }

    public BindingWithBindableConverterParameter(Binding binding)
    {
        Binding = binding;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var multiBinding = new MultiBinding();
        Binding.Mode = Mode;
        multiBinding.Bindings.Add(Binding);
        if (ConverterParameter != null)
        {
            ConverterParameter.Mode = BindingMode.OneWay;
            multiBinding.Bindings.Add(ConverterParameter);
        }
        var adapter = new MultiValueConverterAdapter
        {
            Converter = Converter
        };
        multiBinding.Converter = adapter;
        return multiBinding.ProvideValue(serviceProvider);
    }

    [ContentProperty(nameof(Converter))]
    private class MultiValueConverterAdapter : IMultiValueConverter
    {
        public IValueConverter Converter { get; set; }

        private object lastParameter;

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (Converter == null) return values[0]; // Required for VS design-time
            if (values.Length > 1) lastParameter = values[1];
            return Converter.Convert(values[0], targetType, lastParameter, culture);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            if (Converter == null) return new object[] { value }; // Required for VS design-time

            return new object[] { Converter.ConvertBack(value, targetTypes[0], lastParameter, culture) };
        }
    }
}
两仪 2024-10-14 02:53:57

我找到了一篇相关的SO帖子,我相信它回答了这个问题:

WPF ValidationRule with dependency property

在我的具体示例中,我最终得到的 xaml 看起来像这样实现了上面的示例:

<conv:BindingProxy x:Key="iconCacheHolder" Value="{Binding ElementName=This,Path=IconCache}" />
<conv:UriImageConverter  x:Key="ImageConverter">
    <conv:UriImageConverter.Proxy>
        <conv:IconCacheProxy Value="{Binding Value, Source={StaticResource iconCacheHolder}}" />
    </conv:UriImageConverter.Proxy>
</conv:UriImageConverter>

I have found a related SO post that I believe answers this question:

WPF ValidationRule with dependency property

In my specific example I end up with xaml that looks like this having implemented the above example:

<conv:BindingProxy x:Key="iconCacheHolder" Value="{Binding ElementName=This,Path=IconCache}" />
<conv:UriImageConverter  x:Key="ImageConverter">
    <conv:UriImageConverter.Proxy>
        <conv:IconCacheProxy Value="{Binding Value, Source={StaticResource iconCacheHolder}}" />
    </conv:UriImageConverter.Proxy>
</conv:UriImageConverter>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文