如何在SL5中从标记扩展更新Target对象?

时间:2012-04-19 14:17:51

标签: silverlight-5.0 markup-extensions dependencyobject

我正在Silverlight 5中的标记扩展中尝试此代码。

 public override object ProvideValue(IServiceProvider serviceProvider)
    {
        _target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
        _depObj = _target.TargetObject as DependencyObject;
        _depProp = _target.TargetProperty as DependencyProperty;

        return GetText(TextId, DefaultText);
    }
似乎正确提供了depObj,但是depProp似乎不属于类型  DependencyProperty(类型为Sytem.String(System.Reflection.PropertyInfo))。演员结果为空。

depProp表示正确的Text或Content属性,但没有它  DependencyProperty我无法设置其值。

非常感谢任何输入。

希控

2 个答案:

答案 0 :(得分:0)

不确定为什么它会以PropertyInfo形式出现,但 当然可以使用以下代码设置值:

if (TargetProperty is DependencyProperty)
{
    var dependencyObject = target as DependencyObject;
    if (dependencyObject != null)
    {
        var newValue = GetValue();
        dependencyObject.SetValue(TargetProperty as DependencyProperty, newValue);
    }
}
else if (TargetProperty is PropertyInfo)
{
    var pi = target as PropertyInfo;
    pi.SetValue(target, GetValue(), null);
}

答案 1 :(得分:0)

@Berryl给出的方法可行。但如果你还需要到DependencyProperty,你可以使用这样的东西。此代码还演示了silverlight和WPF之间的细微差别,但两者都可以很好地工作。

仅限Silverlight或WPF,您可以删除#else之前或之后的部分,以简化代码。

但解析依赖属性的部分位于中间(分配_property)。

public override object ProvideValue(IServiceProvider serviceProvider)
{
    IProvideValueTarget Target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

    if (Target == null) {
        throw new InvalidOperationException(
            "Cannot resolve the IProvideValueTarget. Are you binding to a property?");
    }

    /* we need the dependency property (for bindings) */
#if SILVERLIGHT
    PropertyInfo Property = (PropertyInfo)Target.TargetProperty;

    /* resolve the dependency property */
    FieldInfo DepPropertyInfo = Target.TargetObject.GetType()
        .GetField(Property.Name + "Property", BindingFlags.Static | BindingFlags.Public);

    _property = (DependencyProperty)DepPropertyInfo.GetValue(/* obj = */ null);
#else
    _property = Target.TargetProperty as DependencyProperty;
#endif

    if (_property != null) {
#if SILVERLIGHT
        if (Property.Name.StartsWith("Text")) {
            UpdateSourceTrigger = UpdateSourceTrigger.Default;
#else
        if (_property.Name.StartsWith("Text")) {
            UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
#endif
        }
        else {
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        }
    }