假设我有一个这样的 UserControl:
<UserControl
x:Class="SandBox.IconUC"
xmlns:sb="clr-namespace:SandBox"
x:Name="Icon_Control" ...>
<UserControl.Resources>
<sb:IconActualScalingConverter x:Key="IconActualScaling_Converter" />
</UserControl.Resources>
<!-- ... -->
<ScaleTransform.ScaleX>
<MultiBinding Converter="{StaticResource IconActualScaling_Converter}">
<Binding Path="BaseSize" ElementName="Icon_Control" />
<Binding
Path="ScalingOverride"
RelativeSource="{RelativeSource AncestorType=sb:ContainerUC}" />
</MultiBinding>
</ScaleTransform.ScaleX>
<!-- ... -->
</UserControl>
显然,我想根据它自己的依赖属性来缩放它的内容BaseSize
,以及容器 UserControl 在路径中某处通过这个 IconUC 祖先类型的依赖属性ContainerUC
。
当我将 IconUC 设置为一个 ContainerUC 的后代时,这非常有效。
不幸的是,当我将 Icon 放入另一个控件(如 StackPanel)中时,它没有 ContainerUC 作为祖先,我收到以下警告:
System.Windows.Data 警告:4:
找不到与引用
'RelativeSource FindAncestor,AncestorType=' SandBox.ContainerUC ',AncestorLevel='1''的绑定源。
BindingExpression:Path= ScalingOverride ; 数据项=空;
目标元素是“ScaleTransform”(HashCode=51921052);
目标属性为“ScaleX”(类型为“Double”)
这很正常。
如何简单地防止该警告,例如在解析源路径失败时忽略绑定?
我想要的不是解决方法:
- 在 ContainerUC 上使用 DependencyProperty.RegisterAttached,如果没有找到 Ancestor,则在 IconUC 中获取默认元数据值。我知道这是一个很好的解决方法。
- 使用后面的(大量)代码来检索所需的祖先,或者使用默认值。这也有效,我什至不需要转换器。
- 将 StackPanel 放入 ContainerUC。StackPanel 用于测试图标大小。无论如何,图标实际上是更复杂的对象,它们会落在多种类型的容器中,而不仅仅是这个 ContainerUC。
我想要的只是了解它是否存在一种避免错误的方法,即使 MultiBindings 中缺少所需的祖先。
尝试FallbackValue="1.0"
绑定。仍然收到警告。
试过了TargetNullValue="1.0"
。仍然收到警告。
试过了UpdateSourceExceptionFilter="SomeMethod"
。仍然收到警告。
试过了NotifyOnValidationError="False"
。仍然收到警告。
如果答案是否定的,那么在这种情况下,您的 IconUC UserControl 注定是 ContainerUC 的后代,那么我会接受的。:)
这是转换器的简化版本。但我非常怀疑答案(如果有的话)会落在这里:在转换器处理数据之前就发出警告。
public class IconActualScalingConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double definedScaling = (double)values[0];
double scalingFactor = 1.0;
if (values.Length > 1)
{
if (values[1] != DependencyProperty.UnsetValue)
{
scalingFactor = (double)values[1];
}
}
return definedScaling * scalingFactor;
}
public object[] ConvertBack(...)
{
throw new NotImplementedException();
}
}
谢谢。