0

假设我有一个这样的 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”)

这很正常。

如何简单地防止该警告,例如在解析源路径失败时忽略绑定?

我想要的不是解决方法

  1. 在 ContainerUC 上使用 DependencyProperty.RegisterAttached,如果没有找到 Ancestor,则在 IconUC 中获取默认元数据值。我知道这是一个很好的解决方法。
  2. 使用后面的(大量)代码来检索所需的祖先,或者使用默认值。这也有效,我什至不需要转换器。
  3. 将 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();
    }
}

谢谢。

4

0 回答 0