MultiValueConverter 无法绑定到 ViewModel

MultiValueConverter Failing to Bind to ViewModel

HelloAll:我正在尝试创建一个用户控件,它需要一个 MultiValueConverter 来在我的应用程序中缩放 Canvas:

需要

  1. Canvas.ActualWidth
  2. 工程单位的 X 最小值
  3. X 工程单位的最大值

.

public class MultiValueScaleTransform : IMultiValueConverter
{
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
           double numerator     = (double)values[0];
           double denominator   = (double)values[2] - (double)values[1];
           return numerator / denominator;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
}

当我给它输入数字时这似乎工作正常但是当我将我的 XAML 绑定到视图模型时出现问题:

这是错误消息:

Error 7 A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. C:\Users\mwardell\Documents\Visual Studio 2013\Projects\HalliburtonCallouts (12)\HalliburtonCallouts\HalliburtonCallouts\View\UserControls\WellViewUserCtrl.xaml 31 38 HalliburtonCallouts

 <UserControl x:Class="HalliburtonCallouts.View.UserControls.WellViewUserCtrl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:Converters="clr-namespace:HalliburtonCallouts.ViewModel.Converters"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300"
                 x:Name="uc">
        <UserControl.Resources>
            <Converters:ColorToImageBrush x:Key="ColorToBrush"/>
            <Converters:ColorToBitmapBrush x:Key="ColorToImg"/>
            <Converters:ColorToBG x:Key="ColorToBG"/>
            <Converters:ColorToFG x:Key="ColorToFG"/>
            <Converters:MultiValueScaleTransform x:Key="ScaleTransform"/>
            <SolidColorBrush x:Key="BlueBg" Color="#FFA9DCF1"/>
        </UserControl.Resources>
        <Border Background="Red">
            <StackPanel>
                <!-- I used these to make sure the bindings of the user control are working-->
                <TextBlock Text="OverallStartDepth"></TextBlock>
                <TextBlock Text="{Binding OverallStartDepth}"></TextBlock>
                <TextBlock Text="OverallEndDepth"></TextBlock>
                <TextBlock Text="{Binding OverallEndDepth}"></TextBlock>
                <Canvas x:Name="WellCanvas"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource PreviousData}}" >
                 <Canvas.RenderTransform>
                   <ScaleTransform >
                            <ScaleTransform.ScaleX >
                            <MultiBinding Converter="{StaticResource ScaleTransform}">
                                <Binding Path="ActualWidth"/>
                                <Binding Path="{Binding OverallStartDepth, FallbackValue=0.0}"/>
                                <Binding Path="{Binding OverallEndDepth,FallbackValue=100.0}"/>
                            </MultiBinding>
                        </ScaleTransform.ScaleX>

                    </ScaleTransform>
                </Canvas.RenderTransform>
            </Canvas>
        </StackPanel>
        </Border>
    </UserControl>

我确定 OverallEndDepthOverallStartDepth 是可绑定的。请参阅 StackPanel 前四项左右。可绑定性不能证明它们是 Dep 对象的 Dep 属性吗?

如错误所述,您不能使用 {Binding},而是可以通过名称获取元素并从其文本中获取值 属性。

<TextBlock Text="OverallStartDepth"></TextBlock>
<TextBlock Name="OverallStartDepthTextBlock" Text="{Binding OverallStartDepth}"></TextBlock>
<TextBlock Text="OverallEndDepth"></TextBlock>
<TextBlock Name="OverallEndDepthTextBlock" Text="{Binding OverallEndDepth}"></TextBlock>
<MultiBinding Converter="{StaticResource ScaleTransform}">
    <Binding Path="ActualWidth"/>
    <Binding ElementName="OverallStartDepthTextBlock" Path="Text"/>
    <Binding ElementName="OverallEndDepthTextBlock" Path="Text"/>
</MultiBinding>

注: 您可以绑定 OverallEndDepth 是可绑定到任何控件的依赖项 属性 的值。

例如TextBlock.Text 是一个依赖项 属性- SourceCode

    /// <summary>
    /// DependencyProperty for <see cref="Text" /> property.
    /// </summary>
    [CommonDependencyProperty]
    public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register(
                    "Text",
                    typeof(string),
                    typeof(TextBlock),
                    new FrameworkPropertyMetadata(
                            string.Empty,
                            FrameworkPropertyMetadataOptions.AffectsMeasure |
                            FrameworkPropertyMetadataOptions.AffectsRender,
                            new PropertyChangedCallback(OnTextChanged),
                            new CoerceValueCallback(CoerceText)));

    /// <summary>
    /// The Text property defines the content (text) to be displayed.
    /// </summary>
    [Localizability(LocalizationCategory.Text)]
    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

但是,Binding.Path 是一个普通的 属性,无法绑定,因此您会收到上述错误 - SourceCode

/// <summary> The source path (for CLR bindings).</summary>
public PropertyPath Path
{
    get { return _ppath; }
    set
    {
        CheckSealed();

        _ppath = value;
        _attachedPropertiesInPath = -1;
        ClearFlag(BindingFlags.PathGeneratedInternally);

        if (_ppath != null && _ppath.StartsWithStaticProperty)
        {
            if (_sourceInUse == SourceProperties.None || _sourceInUse == SourceProperties.StaticSource ||
                FrameworkCompatibilityPreferences.TargetsDesktop_V4_0) // (for compat - Dev11 738992)
            {
                SourceReference = StaticSourceRef;
            }
            else
                throw new InvalidOperationException(SR.Get(SRID.BindingConflict,  SourceProperties.StaticSource, _sourceInUse));>             }
    }
}

您不能也不会在 MultiBinding 中绑定绑定的 Path 属性。相反,您只需将它们设置为

<TextBlock Text="{Binding OverallStartDepth}">

相当于

<TextBlock Text="{Binding Path=OverallStartDepth}">

还有

<TextBlock>
    <TextBlock.Text>
        <Binding Path="OverallStartDepth"/>
    </TextBlock.Text>
</TextBlock>

所以MultiBinding应该这样写:

<Canvas ... >
    <Canvas.RenderTransform>

        <MultiBinding Converter="{StaticResource ScaleTransform}">
            <Binding Path="ActualWidth" RelativeSource="{RelativeSource AncestorType=Canvas}"/>
            <Binding Path="OverallStartDepth" FallbackValue="0.0"/>
            <Binding Path="OverallEndDepth" FallbackValue="100.0"/>
        </MultiBinding>
    </Canvas.RenderTransform>
</Canvas>

还要确保删除

DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource PreviousData}}"

来自 Canvas