在Dictionary中的Resource中使用ElementName

时间:2012-03-17 11:40:05

标签: wpf xaml data-binding

我在ResourceDictionary中定义了以下内容:

<DockPanel x:Key="errorDisplay" LastChildFill="False">
        <Border Background="Red" DockPanel.Dock="Top">
            <TextBlock x:Name="errorTextBlock" />
        </Border>
        <Canvas DockPanel.Dock="Top" Height="15">
            <Polygon 
                Points="{Binding ElementName=errorDisplay, Path=ActualWidth, Converter={StaticResource PointsToStringArrayConverter},Mode=OneWay}"
                Fill="Red" Stroke="Black" StrokeThickness="1" />                
        </Canvas>
</DockPanel>

在加载用户控件后,此资源将添加到代码中的装饰层中。

但是,我收到了绑定错误

  

(无法找到带参考的绑定源   '的ElementName = errorDisplay')

。我知道名称范围,但是上面应该可以正常工作,因为所有这些都发生在单个复合控件中,并且应用相同的名称范围?

编辑(使用RelativeSource / AncestorType而不是elementname似乎也不起作用。)工作!但实际宽度为零

编辑:使用ElementName = errorTextBlock也会导致相同的绑定错误!

2 个答案:

答案 0 :(得分:1)

您尚未为已提供资源密钥的DockPanel命名。

尝试<DockPanel x:Key="errorDisplay" x:Name="errorDisplay" LastChildFill="False">

但是如你所说,测试时这不起作用。

相对源代码绑定似乎适用于您的代码的这个简化版本:

这是在资源元素

<DockPanel x:Key="errorDisplay" LastChildFill="False">
    <Border Background="Red" DockPanel.Dock="Top">
        <TextBlock x:Name="errorTextBlock" 
         Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DockPanel}}, Path=ActualHeight, Mode=OneWay}" />
    </Border>
</DockPanel>

我正在使用它:

<ContentControl Content="{StaticResource errorDisplay}"/>

答案 1 :(得分:1)

您在使用ElementName=时指向的x:Key不一样。但是,您无法使用x:Name来引用。在MSDN上很难找到为什么它不能被使用,但它可能会被发现将所有部分组合在一起 我猜名称范围没有为ResourceDictionary中的项目注册,仅针对资源字典中项目中的项目。点击ResourceDictionary.FindName上的F1让我这样:http://msdn.microsoft.com/en-us/library/system.windows.resourcedictionary.findname.aspx 它说:“这个字典实现不支持。”猜猜不会回答它,但让我理解我们可能不会轻易自己做到这一点。

作为您问题的答案: 这对我有用:

的ResourceDictionary:

<DockPanel x:Key="errorDisplay" LastChildFill="False">
    <Border Background="Red" DockPanel.Dock="Top">
      <TextBlock x:Name="errorTextBlock" />
    </Border>
    <Canvas DockPanel.Dock="Top" Height="15">
      <Polygon Points="{Binding RelativeSource={RelativeSource AncestorType=DockPanel}, Path=ActualWidth, Converter={StaticResource PointsToStringArrayConverter},Mode=OneWay}" 
               Fill="Red" Stroke="Black" StrokeThickness="1" />
    </Canvas>
  </DockPanel>

MainWindow:

<ContentPresenter Content="{StaticResource errorDisplay}"/>

转换器:

  public class PointsToStringArrayConverter : IValueConverter
  {
    public object Convert( object value , Type targetType , object parameter , System.Globalization.CultureInfo culture )
    {
      if ( !( value is double ) ) { return value; }
      var dbl = ( double )value;
      PointCollection p = new PointCollection( );
      p.Add( new Point( dbl , dbl ) );
      p.Add( new Point( dbl/2 , dbl ) );
      p.Add( new Point( dbl , dbl/2 ) );
      p.Add( new Point( dbl /2, dbl/2 ) );
      return p;
    }

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

你说你已经尝试过使用RelativeSource,但是试着在你的转换器中放一个断点,看它是否被触发。

欲了解更多信息: 名称范围:http://msdn.microsoft.com/en-us/library/ms746659.aspx 资源:http://msdn.microsoft.com/en-us/library/ms742538.aspx