나는이 작업을 수행 할 수있는 방법이 있나요 Style
:
<Style TargetType="FrameworkElement">
<Setter Property="Visibility">
<Setter.Value>
<Binding Path="Tag"
RelativeSource="{RelativeSource AncestorType=UserControl}"
Converter="{StaticResource AccessLevelToVisibilityConverter}"
ConverterParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag}" />
</Setter.Value>
</Setter>
</Style>
Tag
최상위 상위 부모와 Tag
제어 자체를 변환기 클래스 로 보내면 됩니다.
답변
ConverterParameter
는 종속성 속성이 아니기 때문에 속성은 바인딩 할 수 없습니다.
이후 Binding
로부터 유도되지 않는 DependencyObject
속성 중에 종속성 속성 일 수있다. 결과적으로 바인딩은 다른 바인딩의 대상 객체가 될 수 없습니다.
그러나 다른 해결책이 있습니다. 일반 바인딩 대신 다중 값 변환기MultiBinding
와 함께 a를 사용할 수 있습니다 .
<Style TargetType="FrameworkElement">
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource AccessLevelToVisibilityConverter}">
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=FindAncestor,
AncestorType=UserControl}"/>
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
다중 값 변환기는 소스 값 배열을 입력으로 가져옵니다.
public class AccessLevelToVisibilityConverter : IMultiValueConverter
{
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.All(v => (v is bool && (bool)v))
? Visibility.Visible
: Visibility.Hidden;
}
public object[] ConvertBack(
object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
답변
때문에 아니, 불행하게도이 할 수 없습니다 ConverterParameter
하지 않는 것입니다 DependencyProperty
당신이 바인딩을 사용할 수 없습니다 있도록
그러나 아마도 속임수를 사용하여 MultiBinding
with IMultiValueConverter
2 Tag
속성 을 전달할 수 있습니다.
답변
사용하는 다른 방법도 있습니다 MarkupExtension
사용하기 위해서는 Binding
A에 대한이 ConverterParameter
. 이 솔루션을 사용하면 첫 번째 샘플에서 예상 한 것과 같이 전달 되기 때문에 IValueConverter
대신 기본값을 계속 사용할 수 있습니다 .IMultiValueConverter
ConverterParameter
IValueConverter
재사용 할 수있는 내용은 다음과 같습니다 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) };
}
}
}
이를 MarkupExtension
코드 기반으로 사용하면 ConverterParameter
다음과 같은 방식으로 바인딩 할 수 있습니다 .
<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>
초기 제안과 거의 같습니다.