2015-10-14 253 views
1

我一直在关注此answer以显示我的用户控件的一些属性。WPF绑定找不到与参考绑定的源

问题是绑定没有找到源,我不明白如何正确地做到这一点。

XAML:

<UserControl x:Class="Project.UI.Views.ucFilterDataGrid" 
     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:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:Project.UI.Views" 
     xmlns:watermark="clr-namespace:Project.UI.Watermark" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<StackPanel> 
    <StackPanel.Resources> 
     <Style TargetType="{x:Type TextBox}"> 
      <Setter Property="Margin" Value="0,0,00,30"/> 
     </Style> 
    </StackPanel.Resources> 
    <AdornerDecorator> 
     <TextBox Name="SearchTextBox"> 
      <watermark:WatermarkService.Watermark> 
       <TextBlock Name="waterMarkText" 
          Text="{Binding Path=WatermarkContent, 
            RelativeSource={RelativeSource FindAncestor, 
            AncestorType=local:ucFilterDataGrid}}" 
          HorizontalAlignment="Center" > 

       </TextBlock> 
      </watermark:WatermarkService.Watermark> 
     </TextBox> 
    </AdornerDecorator> 

    <DataGrid Name="Results"> 

    </DataGrid> 
</StackPanel> 

CS:

namespace Project.UI.Views 
{ 
/// <summary> 
/// Interaction logic for ucFilterDataGrid.xaml 
/// </summary> 
public partial class ucFilterDataGrid : UserControl 
{ 
    public ucFilterDataGrid() 
    { 
     InitializeComponent(); 
    } 


    public string WatermarkContent 
    { 
     get { return GetValue(WatermarkContentProperty).ToString(); } 
     set { SetValue(WatermarkContentProperty, value); } 
    } 

    public static readonly DependencyProperty WatermarkContentProperty = DependencyProperty.Register("WatermarkContent", typeof(string), typeof(ucFilterDataGrid), new FrameworkPropertyMetadata(string.Empty)); 
} 
} 

窗口:

<Grid> 
    <local:ucFilterDataGrid Margin="301,34,31,287" WatermarkContent="MyTest"/> 
</Grid> 

其结果将是一个空白的TextBlock。如果我只是从我的水印UserControl中删除它并将它放在与DataGrid相同的级别上,它将起作用。

+0

一些信息/你的用户控件水印XAML可能的帮助。这里我没有看到任何明显的错误。 – Rowbear

+0

更改绑定到自引用&检查。 –

回答

5

的问题是你的TextBlock被设置为附加属性的值,这就是:

<watermark:WatermarkService.Watermark> 
      <TextBlock ...> 
      </TextBlock> 
</watermark:WatermarkService.Watermark> 

watermark:WatermarkService.Watermark是附加属性。它的价值只是记忆中的一个对象,与视觉树分离。所以你不能使用绑定RelativeSourceElementName。您需要一些代理来弥补断开连接。该Source将用于绑定,你应该尝试的代码如下:

<TextBox Name="SearchTextBox"> 
     <TextBox.Resources> 
      <DiscreteObjectKeyFrame x:Key="proxy" 
            Value="{Binding Path=WatermarkContent, 
              RelativeSource={RelativeSource FindAncestor, 
              AncestorType=local:ucFilterDataGrid}}"/> 
     </TextBox.Resources> 
     <watermark:WatermarkService.Watermark> 
      <TextBlock Name="waterMarkText" 
         Text="{Binding Value, Source={StaticResource proxy}}" 
         HorizontalAlignment="Center" > 

      </TextBlock> 
     </watermark:WatermarkService.Watermark> 
</TextBox> 
+1

很好的解释! –

1

我前几天做了类似的事情,如果我没有记错的话。您必须从INotifyPropertyChanged接口派生出来,并告诉组件,无论何时更新WatermarkContent,该属性都已更改。否则,xaml(视图)将不知道何时更改文本,并且绑定不会更新。

这里是你可以尝试

using System.ComponentModel; 

public partial class ucFilterDataGrid : UserControl, INotifyPropertyChanged 
{ 
    public static readonly DependencyProperty WatermarkContentProperty = DependencyProperty.Register("WatermarkContent", typeof(string), typeof(ucFilterDataGrid), new FrameworkPropertyMetadata(string.Empty)); 
    public event PropertyChangedEventHandler PropertyChanged; 

    public ucFilterDataGrid() 
    { 
     InitializeComponent(); 
    } 

    public string WatermarkContent 
    { 
     get { GetValue(WatermarkContentProperty).ToString(); } 
     set { 
      SetValue(WatermarkContentProperty, value); 
      RaisePropertyChanged(); 
     } 
    } 

    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

我已经添加了INotifyPropertyChanged的,并且每个WatermarkContent改变时引发事件。

希望它有帮助!这里