ToString()
이 object
및 ICommand
에 선언하는 것은 인터페이스 인 object
없습니다. 은부터 object
까지만 지정할 수 있습니다.
바인딩 시스템은 이미 말했듯이 선언 된 유형을 구분하지 않습니다. 그러나 string
으로 변환 할 때 기본값 인 IValueConverter
이 사용됩니다.
내부적으로 프레임 워크는 사용자 정의 변환기가 제공되지 않을 때 DefaultValueConverter
을 사용합니다. 다른의 속성에 바인딩 할 때 사용자가 IValueConverter
정의 제공해야 문서에 따르면
internal static IValueConverter Create(Type sourceType,
Type targetType,
bool targetToSource,
DataBindEngine engine)
{
TypeConverter typeConverter;
Type innerType;
bool canConvertTo, canConvertFrom;
bool sourceIsNullable = false;
bool targetIsNullable = false;
// sometimes, no conversion is necessary
if (sourceType == targetType ||
(!targetToSource && targetType.IsAssignableFrom(sourceType)))
{
return ValueConverterNotNeeded;
}
// the type convert for System.Object is useless. It claims it can
// convert from string, but then throws an exception when asked to do
// so. So we work around it.
if (targetType == typeof(object))
{
// The sourceType here might be a Nullable type: consider using
// NullableConverter when appropriate. (uncomment following lines)
//Type innerType = Nullable.GetUnderlyingType(sourceType);
//if (innerType != null)
//{
// return new NullableConverter(new ObjectTargetConverter(innerType),
// innerType, targetType, true, false);
//}
//
return new ObjectTargetConverter(sourceType, engine);
}
else if (sourceType == typeof(object))
{
// The targetType here might be a Nullable type: consider using
// NullableConverter when appropriate. (uncomment following lines)
//Type innerType = Nullable.GetUnderlyingType(targetType);
// if (innerType != null)
// {
// return new NullableConverter(new ObjectSourceConverter(innerType),
// sourceType, innerType, false, true);
// }
//
return new ObjectSourceConverter(targetType, engine);
}
// use System.Convert for well-known base types
if (SystemConvertConverter.CanConvert(sourceType, targetType))
{
return new SystemConvertConverter(sourceType, targetType);
}
// Need to check for nullable types first, since NullableConverter is a bit over-eager;
// TypeConverter for Nullable can convert e.g. Nullable<DateTime> to string
// but it ends up doing a different conversion than the TypeConverter for the
// generic's inner type, e.g. bug 1361977
innerType = Nullable.GetUnderlyingType(sourceType);
if (innerType != null)
{
sourceType = innerType;
sourceIsNullable = true;
}
innerType = Nullable.GetUnderlyingType(targetType);
if (innerType != null)
{
targetType = innerType;
targetIsNullable = true;
}
if (sourceIsNullable || targetIsNullable)
{
// single-level recursive call to try to find a converter for basic value types
return Create(sourceType, targetType, targetToSource, engine);
}
// special case for converting IListSource to IList
if (typeof(IListSource).IsAssignableFrom(sourceType) &&
targetType.IsAssignableFrom(typeof(IList)))
{
return new ListSourceConverter();
}
// Interfaces are best handled on a per-instance basis. The type may
// not implement the interface, but an instance of a derived type may.
if (sourceType.IsInterface || targetType.IsInterface)
{
return new InterfaceConverter(sourceType, targetType);
}
// try using the source's type converter
typeConverter = GetConverter(sourceType);
canConvertTo = (typeConverter != null) ? typeConverter.CanConvertTo(targetType) : false;
canConvertFrom = (typeConverter != null) ? typeConverter.CanConvertFrom(targetType) : false;
if ((canConvertTo || targetType.IsAssignableFrom(sourceType)) &&
(!targetToSource || canConvertFrom || sourceType.IsAssignableFrom(targetType)))
{
return new SourceDefaultValueConverter(typeConverter, sourceType, targetType,
targetToSource && canConvertFrom, canConvertTo, engine);
}
// if that doesn't work, try using the target's type converter
typeConverter = GetConverter(targetType);
canConvertTo = (typeConverter != null) ? typeConverter.CanConvertTo(sourceType) : false;
canConvertFrom = (typeConverter != null) ? typeConverter.CanConvertFrom(sourceType) : false;
if ((canConvertFrom || targetType.IsAssignableFrom(sourceType)) &&
(!targetToSource || canConvertTo || sourceType.IsAssignableFrom(targetType)))
{
return new TargetDefaultValueConverter(typeConverter, sourceType, targetType,
canConvertFrom, targetToSource && canConvertTo, engine);
}
// nothing worked, give up
return null;
}
: 인터페이스는 다르게 행동 할 것이다 왜 Create
방법 당신은 여기에 (sourceType.IsInterface
의 특정 검사에 대한보고) 개체를 볼 수 있습니다 형식으로 당신이 바인딩되는 종속성 속성보다 호출되는 ToString
프레임 워크의 기본 변환 메커니즘의 구현 세부 사항입니다 (그리고 내가 아는 한 문서화되지 않은, 잘 정의 된 상황에 대한 기본 및 대체 값을 나타냅니다) 변경할 수 있습니다 언제든지.
사실입니다.하지만 WPF가 먼저 선언 된 속성 유형을 조사하는 이유는 무엇입니까? 실제로 반환되는 것을 보지 않아야합니까? –
수정 됨. InterfaceConverter는 다른 것들과 다르게 작동합니다. 이것은 C# 4.0 소스에서 온 것입니다. 그래서 초기의 대답은 조금 벗어났습니다. 왜냐하면 Type.IsInterface는 다른 선언 된 속성 유형에 대해 다른 값을 반환하기 때문에 더 많은 것입니다. – MrDosu
뭔가 흥미로운 점은 속성을 MyExampleCommand (미리 public으로 설정)로 선언하면 버튼이 여전히 비어있는 것입니다. MyExampleCommand가 더 이상 ICommand를 구현하지 않으면 ToString이 제대로 호출된다. 이것이 어떻게 관련이 있습니까? 즉, propery 선언에서 직접 언급되지 않은 일부 인터페이스를 구현하면 아무 것도 변경되지 않는 이유는 무엇입니까? –