Ngoài ra còn có một cách khác để sử dụng MarkupExtension
để sử dụng Binding
cho a ConverterParameter
. Với giải pháp này, bạn vẫn có thể sử dụng mặc định IValueConverter
thay IMultiValueConverter
vì vì ConverterParameter
được truyền vào IValueConverter
giống như bạn mong đợi trong mẫu đầu tiên của mình.
Đây là tái sử dụng của tôi MarkupExtension
:
/// <summary>
/// <example>
/// <TextBox>
/// <TextBox.Text>
/// <wpfAdditions:ConverterBindableParameter Binding="{Binding FirstName}"
/// Converter="{StaticResource TestValueConverter}"
/// ConverterParameterBinding="{Binding ConcatSign}" />
/// </TextBox.Text>
/// </TextBox>
/// </example>
/// </summary>
[ContentProperty(nameof(Binding))]
public class ConverterBindableParameter : MarkupExtension
{
#region Public Properties
public Binding Binding { get; set; }
public BindingMode Mode { get; set; }
public IValueConverter Converter { get; set; }
public Binding ConverterParameter { get; set; }
#endregion
public ConverterBindableParameter()
{ }
public ConverterBindableParameter(string path)
{
Binding = new Binding(path);
}
public ConverterBindableParameter(Binding binding)
{
Binding = binding;
}
#region Overridden Methods
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);
}
#endregion
[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) };
}
}
}
Với điều này MarkupExtension
trong cơ sở mã của bạn, bạn có thể chỉ cần liên kết ConverterParameter
theo cách sau:
<Style TargetType="FrameworkElement">
<Setter Property="Visibility">
<Setter.Value>
<wpfAdditions:ConverterBindableParameter Binding="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}"
Converter="{StaticResource AccessLevelToVisibilityConverter}"
ConverterParameterBinding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag}" />
</Setter.Value>
</Setter>
Mà trông gần giống như đề xuất ban đầu của bạn.
MultiValueConverterAdapter
là mất tích. Tôi tìm thấy nó ở đây .