2015-10-14 255 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改變時引發事件。

希望它有幫助!這裏