XAML에 여러 값 변환기를 연결하는 방법이 있습니까?
두 개의 개별 변환을 수행 한 후 데이터 컨텍스트의 속성에 바인딩 된 정수 값을 표시 해야하는 상황이 있습니다.
- 범위 내에서 값을 뒤집습니다 (예 : 범위는 1 ~ 100, 데이터 컨텍스트의 값은 90, 사용자는 10의 값을 봅니다)
- 숫자를 문자열로 변환
내 변환기 (IValueConverter를 구현하는)를 만들어 두 단계를 모두 수행 할 수 있음을 알고 있습니다. 그러나 이미 첫 번째 단계 만 수행하는 별도의 값 변환기가 있으며 두 번째 단계는 Int32Converter로 덮여 있습니다.
이 두 개의 기존 클래스를 집계하는 추가 클래스를 만들지 않고 XAML에 연결할 수있는 방법이 있습니까?
이 중 하나라도 명확히해야하는 경우 알려주십시오. :)
감사.
내가 사용하는 이 방법 내 실버 라이트 프로젝트에 가레스 에반스에 의해합니다.
여기 내 구현이 있습니다.
public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
그런 다음 XAML에서 다음과 같이 사용할 수 있습니다.
<c:ValueConverterGroup x:Key="InvertAndVisibilitate">
<c:BooleanInverterConverter/>
<c:BooleanToVisibilityConverter/>
</c:ValueConverterGroup>
Josh Smith : Piping Value Converters (archive.org link)의 도움으로 내가 찾던 것을 정확히 찾았습니다 .
그는 ValueConverterGroup
XAML에서 내가 바랐던 그대로 사용 하는 클래스를 정의합니다 . 예를 들면 다음과 같습니다.
<!-- Converts the Status attribute text to a SolidColorBrush used to draw
the output of statusDisplayNameGroup. -->
<local:ValueConverterGroup x:Key="statusForegroundGroup">
<local:IntegerStringToProcessingStateConverter />
<local:ProcessingStateToColorConverter />
<local:ColorToSolidColorBrushConverter />
</local:ValueConverterGroup>
좋은 물건. 고마워요, 조쉬 :)
타운의 구현 의 가레스 에반스의 실버 라이트 프로젝트 는 다른 컨버터 매개 변수를 지원하지 않습니다하지만, 아주 좋습니다.
쉼표로 구분 된 매개 변수를 제공 할 수 있도록 수정했습니다 (물론 탈출하지 않는 한).
변환기:
public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
private string[] _parameters;
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(parameter != null)
_parameters = Regex.Split(parameter.ToString(), @"(?<!\\),");
return (this).Aggregate(value, (current, converter) => converter.Convert(current, targetType, GetParameter(converter), culture));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
private string GetParameter(IValueConverter converter)
{
if (_parameters == null)
return null;
var index = IndexOf(converter as IValueConverter);
string parameter;
try
{
parameter = _parameters[index];
}
catch (IndexOutOfRangeException ex)
{
parameter = null;
}
if (parameter != null)
parameter = Regex.Unescape(parameter);
return parameter;
}
}
참고 : ConvertBack은 여기에서 구현되지 않습니다 . 정식 버전 은 내 요지 를 참조하십시오 .
Implementation:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:converters="clr-namespace:ATXF.Converters;assembly=ATXF" x:Class="ATXF.TestPage">
<ResourceDictionary>
<converters:ValueConverterGroup x:Key="converters">
<converters:ConverterOne />
<converters:ConverterTwo />
</converters:ValueConverterGroup>
</ResourceDictionary>
<Label Text="{Binding InitialValue, Converter={StaticResource converters}, ConverterParameter='Parameter1,Parameter2'}" />
</ContentPage>
Yes, there are ways to chain converters but it does not look pretty and you don't need it here. If you ever come to need this, ask yourself is that really the way to go? Simple always works better even if you have to write your own converter.
In your particular case, all you need to do is format a converted value to a string. StringFormat
property on a Binding
is your friend here.
<TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />
Here is a small extension of Town's answer to support multi-binding:
public class ValueConverterGroup : List<IValueConverter>, IValueConverter, IMultiValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Convert(values as object, targetType, parameter, culture);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
'Programing' 카테고리의 다른 글
SQLite에 Long 유형이 있습니까? (0) | 2020.07.18 |
---|---|
Django REST Framework : ModelSerializer에 추가 필드 추가 (0) | 2020.07.18 |
두 날짜 사이의 일? (0) | 2020.07.18 |
Angular4-양식 제어를위한 값 접근자가 없음 (0) | 2020.07.18 |
도커 머신 : 기기에 남은 공간이 없습니다. (0) | 2020.07.18 |