标记扩展和对象创建
本文关键字:对象 创建 扩展 | 更新日期: 2023-09-27 17:54:53
目前我有这样的标记
<TextBlock>
<TextBlock.Text>
<Binding Path="Value" ElementName="window" ConverterParameter="M">
<Binding.Converter>
<local:DatePartValueConverter />
</Binding.Converter>
</Binding>
</TextBlock.Text>
</TextBlock>
我想把它缩短成这样
<TextBlock Text="{Binding Path=Value,ElementName=window,
ConverterParameter=M,Converter={local:DatePartValueConverter}}" />
但是编译器卡住了,因为DatePartValueConverter不是从MarkupExtension派生的。是否没有其他方法来获取短格式标记来创建DatePartValueConverter的实例?
顺便说一下,我尝试从MarkupExtension派生,它确实解决了这个问题。我的ProvideValue实现看起来像这样
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new DatePartValueConverter();
}
,它工作,但我仍然不清楚serviceProvider
的起源和性质,以及人们可能期望用它做什么。
有趣的是,当我在使用这个标记扩展的绑定上使用Visual Studio 2012绑定编辑器时,它立即再次展开它,使得整个标记扩展支持的事情有点毫无意义。
我可能应该提到,我需要为每个绑定一个私有实例,因为它维护内部状态——它需要知道整个DateTime值来设置某些方面,就像这样
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
culture = System.Globalization.CultureInfo.CurrentCulture;
var strValue = value as string;
int y = _value.Year, M = _value.Month, d = _value.Day,
H = _value.Hour, m = _value.Minute, s = _value.Second;
if (strValue == null)
return null;
else
{
string p = parameter as string;
switch (p)
{
case "yyyy":
y = int.Parse(strValue); break;
case "yy":
y = (strValue.Length == 4) ?
int.Parse(strValue) :
int.Parse(DateTime.Now.Year.ToString().Substring(0, 2) + strValue);
break;
case "M":
case "MM":
M = int.Parse(strValue); break;
...
}
}
return new DateTime(y, M, d, H, m, s);
}
您可以创建一个DatePartValueConverter
实例作为资源,然后使用它。
<Window.Resources>
<local:DatePartValueConverter x:Key="datePartValueConverter" />
</Window.Resources>
<TextBlock Text="{Binding Path=Value, ElementName=window,
ConverterParameter=M, Converter={StaticResource datePartValueConverter}}" />
EDIT如果您确实想使转换器成为MarkupExtension
,那么您可以这样做。您可以在ProvideValue
中返回一个新实例,也可以使用return this;
返回当前实例
通过返回当前实例,您可以在转换器中拥有属性,并允许您做这样的事情。
public class DatePartValueConverter : MarkupExtension, IValueConverter {
public string ParseType { get; set; }
// other methods
}
<TextBlock Text="{Binding Path=Value, ElementName=window,
Converter={local:DatePartValueConverter ParseType=M}}" />
对于IServiceProvider
,请参见MarkupExtension。ProvideValue -是否实际使用了IServiceProvider ?
除了从MarkupExtension
派生您的转换器之外,我所知道的唯一方法是创建您自己的自定义绑定类(看看DelayBinding
)。