我遇到一种情况,需要使用here所述的技术来解决绑定是指RelativeSource
的绑定。我正在使用自定义标记扩展名,以允许将实际的Binding对象分配给DependencyProperty
,但是不幸的是,当我尝试对Value
中的DummyDO
应用绑定时,它试图找到我的路径(例如在与Background
等效标识的RelativeSource
上的DummyDO
)(不存在)。
我希望我可以通过存储传递到serviceProvider
的ProvideValue
属性并使用
return this.TargetBinding.ProvideValue((IProvideValueTarget)this.ServiceProvider);
从标记扩展在稍后的位置,但这会导致一个非常奇怪的null引用异常,其中没有可访问的null(我猜是某个引用已经以某种方式无效)。
另一种方法是在我的
ProvideValue
方法期间存储属性的实际来源,然后创建ProvideCurrentValue
的新方法,稍后再根据DummyDO
方法重新评估绑定。我只是想不出该怎么做!任何帮助将非常感激。代码如下:
XAML
<StackPanel>
<Button
h:ResponsiveBrush.CentreTrackBrush="True"
h:ResponsiveBrush.Binding="{e:PassBinding TargetBinding={Binding Background,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}}}}"
>
<Button.Content>Try Me</Button.Content>
</Button>
</StackPanel>
(h:ResponsiveBrush与我们所追求的不相关-这是我要尝试附加的行为,而这的关键部分是在某个时候它需要解析通过PassBindingExtension传递的Binding对象)
标记扩展
public class PassBindingExtension : MarkupExtension
{
public PassBindingExtension() { }
public PassBindingExtension(Binding targetBinding)
{
this.TargetBinding = targetBinding;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var valueGetter = serviceProvider as IProvideValueTarget;
if (valueGetter != null)
{
// Get the object. NB that this will evaluate to a
// BUTTON given the XAML above NOT a StackPanel as I was hoping
this.TargetObject = valueGetter.TargetObject;
this.TargetProperty = valueGetter.TargetProperty;
/*
Ideally around here I need to evaluate the object to which
this. TargetBinding refers around here so I can get the correct
value later.
*/
}
/*
Addendum: If I try the following at this point, my application vanishes into
oblivion
var oOriginalValue = this.TargetBinding.ProvideValue(serviceProvider);
Not sure if that's intended or not, but since I don't need to get the
original value, I just need the info to work out where the future value
should come from, I'm not too fussed.
*/
return this;
}
public object ProvideValueLate()
{
object oOut = null;
/* Somehow, here, I need to reliably obtain
the value of TargetProperty on the
RelativeSource that would be evaluated with
respect to TargetObject
*/
return oOut;
}
[ConstructorArgument("targetBinding")]
public Binding TargetBinding { get; set; }
public object TargetObject { get; set; }
public object TargetProperty { get; set; }
// Obsolete - doesn't work
public IServiceProvider ServiceProvider { get; set; }
// Was hoping this would let me sidestep the issue, but lamentably it doesn't
public object ProvideValueLate_Old()
{ return this.TargetBinding.ProvideValue((IProvideValueTarget)this.ServiceProvider); }
}
最佳答案
是的,尚未能够精确地解决此问题,但确实根据以下方法使用了一种解决方法:{Binding RelativeSource={RelativeSource Self}}
通过标准依赖项属性评估所讨论的对象,其中Self可以是任何RelativeSource。
因此,在附加的行为上创建两个属性,一个用于我们想要属性的对象,另一个用于属性路径。将它们称为SourceObject和SourcePath。
使用下面的方法来获取现有值。这是在h:ResponsiveBrush的事件处理程序中-我没有设法使用标记扩展名来完成这项工作(这是我想要的,但不能全部使用...):
string sourcePath = ((DependencyObject)sender).GetValue(SourcePathProperty);
DependencyObject sourceObject = ((DependencyObject)sender).GetValue(SourceObjectProperty);
Binding b = new Binding(sourcePath) {Source = sourceObject};
RadialGradientBrush sourceBrush = DependencyInterpreter.EvalBinding(b) as RadialGradientBrush;
为我提供了所需的信息,但由于它无法回答问题,因此我暂时不接受此答案-只是为其他类似情况的人提供了一种解决方法。如果有人对为什么“标记扩展”方法不起作用有答案,我仍然会非常感兴趣。
关于c# - 如何在代码中评估RelativeSource对象以提供等效的有效Source,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27568421/