MultiValueConverter 无法绑定到 ViewModel
MultiValueConverter Failing to Bind to ViewModel
HelloAll:我正在尝试创建一个用户控件,它需要一个 MultiValueConverter 来在我的应用程序中缩放 Canvas:
需要
- Canvas.ActualWidth
- 工程单位的 X 最小值
- 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>
我确定 OverallEndDepth
和 OverallStartDepth
是可绑定的。请参阅 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
HelloAll:我正在尝试创建一个用户控件,它需要一个 MultiValueConverter 来在我的应用程序中缩放 Canvas:
需要
- Canvas.ActualWidth
- 工程单位的 X 最小值
- 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>
我确定 OverallEndDepth
和 OverallStartDepth
是可绑定的。请参阅 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