.net 绑定到转换器参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4388326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 15:00:58  来源:igfitidea点击:

Binding to Converter Parameter

.netxamlbindingsilverlight-4.0converter

提问by dparker

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

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

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

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

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}}"
/>

回答by Joe McBride

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.

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

回答by Tim Greenfield

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:

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

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

    <c:ConverterParamHelper.Converter>

        <c:RealConverter/>

    </c:ConverterParamHelper.Converter>

</c:ConverterParamHelper>

回答by Adam Bilinski

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:

并在您的 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" />

回答by Mark

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

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

WPF ValidationRule with dependency property

具有依赖属性的 WPF ValidationRule

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

在我的具体示例中,我最终得到了实现上述示例的 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>

回答by Apfelkuacha

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

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

<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) };
        }
    }
}