IValueConverter에 MarkupExtension 더하기

안녕하세요. :smile:

WPF Converter 관련 간단한 팁입니다.

MarkupExtension

WPF Converter를 만들 때 IValueConverter와 이것을 함께 상속받아 만들게 되면
Xaml에서 Converter를 사용할 때 Resource Key를 따로 만들지 않아도 됩니다.

BooleanToVisibilityConverter.cs

public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter
{
	public object Convert(object value, Type targetType,
		object parameter, CultureInfo culture)
	{
		return value.Equals(true) ? Visibility.Visible : Visibility.Collapsed;
	}

	public object ConvertBack(object value, Type targetType,
		object parameter, CultureInfo culture)
	{
		throw new NotImplementedException();
	}

	public override object ProvideValue(IServiceProvider serviceProvider)
	{
		return this;
	}
}

Xaml에서 사용할 때

<Border Visibility"="{Binding IsVisible, FallbackValue=Collapsed, 
                              Converter ={cnvts:BooleanToVisibilityConverter}}"/>

저도 최근에 알고 사용해보고 있는데요.
혹시 문제되는 부분이 있거나 원래 사용하고 계신 분들의 의견도 듣고 싶습니다. :smile:

(그리고 혹시 문제가 있는 부분이 있을 경우 질문 게시판으로 옮길 수도 있어요!)

읽어주셔서 감사합니다.

6개의 좋아요

오…!! 이것은 정말 특급 꿀이군요 ㅎㅎㅎ 감사합니다 james님!

1개의 좋아요

머릿속으론 "가능하겠지?"라고 생각했었으나 실제로 실험한 적이 없어 참 궁금했던 부분인데 실험해주셔서 감사합니다 :slight_smile:

2개의 좋아요

저는 Converter 타입에 MarkupExtension 의 멤버가 보이는 게 싫어서 이런 식으루 쓰고 있어욜 `=ㅂ=

public abstract class ConverterMarkupExtension<T> : MarkupExtension, IValueConverter
     where T : class, new()
{
    private static Lazy<T> _converter = new Lazy<T>(() => new T());

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return _converter.Value;
    }

    public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);

    public abstract object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}

public abstract class MultiConverterMarkupExtension<T> : MarkupExtension, IMultiValueConverter
     where T : class, new()
{
    private static Lazy<T> _converter = new Lazy<T>(() => new T());

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return _converter.Value;
    }

    public abstract object Convert(object[] values, Type targetType, object parameter, CultureInfo culture);

    public abstract object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture);
}

public class InversionBoolConverter : ConverterMarkupExtension<InversionBoolConverter>
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            return (bool)value == false;
        }
        catch
        {
            return Binding.DoNothing;
        }
    }

    public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


public class CanPanTiltCheckConverter : MultiConverterMarkupExtension<CanPanTiltCheckConverter>
{
    public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            var isLive = (bool)values[0];                
            var isDrone = (bool)values[1];
            var isIPconverter = (bool)values[2];

            var canPanTilt = isLive && (isDrone || isIPconverter);

            Debug.WriteLine($"[DebugConverter] IsLive:{isLive}, IsDrone:{isDrone}, IsIPConverter:{isIPconverter}");

            return canPanTilt;
        }
        catch
        {
            return Binding.DoNothing;
        }
    }

    public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

5개의 좋아요