2014-09-04 1 views
1

다음 xaml을 사용하여 WatermarkTextBox를 직접 만들었습니다.Selfmade WatermarkTextBox

<Grid> 
    <TextBlock Margin="5 0 5 0" 
       VerticalAlignment="Center" 
       Foreground="{Binding WatermarkForeground, FallbackValue=#DBDBDB}" 
       Text="{Binding Watermark, FallbackValue=This prompt dissappears as you type...}" 
       Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}" /> 
    <TextBox Name="txtUserEntry" 
      Background="Transparent" 
      BorderThickness="0" 
      Foreground="{Binding TextForeground, FallbackValue=Black}" 
      VerticalAlignment="Center" 
      Text="{Binding Text}" /> 
</Grid> 

다음 코드는 내가 아는 한 INotifyPropertyChanged을 태어나 셨하지 않는 뒤에 코드입니다. 이 DependencyProperty으로 충분해야합니다.

public String Watermark 
{ 
    get { return (String)GetValue(WatermarkProperty); } 
    set { SetValue(WatermarkProperty, value); } 
} 

public String Text 
{ 
    get { return (String)GetValue(TextProperty); } 
    set { SetValue(TextProperty, value); } 
} 

public static readonly DependencyProperty WatermarkProperty = 
    DependencyProperty.Register("Watermark", typeof(string), 
    typeof(WatermarkTextBox), new PropertyMetadata("")); 

public static readonly DependencyProperty TextProperty = 
    DependencyProperty.Register("Text", typeof(string), 
    typeof(WatermarkTextBox), new PropertyMetadata("")); 

그런 다음 내 응용 프로그램에서는 이와 같이 사용합니다.

<c:WatermarkTextBox Watermark="[Design] Name *" 
        Text="{Binding Name, FallbackValue='Name'}" /> 

응용 프로그램을 실행할 때 TextBlock의 워터 마크로 "[Design] Name *"이 표시됩니다. 위의 예에서 DP Text은 내 ViewModel의 Name 속성에 바인딩되어 있습니다.

public string Name { get; set; } 

ViewModel은 INotifyPropertyChanged을 구현합니다. 나는 버튼을 누르면 내 뷰 모델에서 조금 더

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

, 다음 코드

Name = "Test"; 

Test은 결코 WatermarkTextBox에 표시하고 싶어 단어를 실행합니다. 런타임에 내용을 입력하고 Name 속성을 요청하더라도 여전히 null을 반환합니다.

이렇게하면 더 명확하게 처리됩니까?

정규로 TextBox으로 바인딩을 테스트했다. 여기서는 바인딩이 제대로 작동하는 것으로 보입니다. 나는 문제가 내 WatermarkTextBox 내부에 있다고 생각하지만 나는 어디에서 모를 것이다.

<TextBox Text="{Binding Name, FallbackValue='Name'}" /> 
+1

귀하의 질문은 거의 의미가 ... 당신은 * 전에 * 당신이 그것을 게시 읽어야합니다. 당신은 (대략) 'Watermark' 속성을 설정할 때'내 컨트롤이 작동하지만, 'Name' 속성을 설정할 때 ...'라고 말한 것은 ... 당신이 다른 속성을 설정할 때 왜 똑같은 일을합니까? 'Name' 속성과 'Watermark' 속성의 관계는 무엇입니까? – Sheridan

+0

코드와 xaml이 불완전합니다. 사용자 정의 컨트롤을 만드시겠습니까? 완전한 코드와 xaml을 게시하시기 바랍니다. 나는 그저 당신의 c : WaterMarkTextBox를 보았다. cc 파일을 만들었고 바인딩이 틀린 경우 findanchestor 또는 TemplateBinding을 사용해야합니다 (http://www.nbdtech.com/Free/WpfBinding.pdf).귀하의 이름 자동 속성 (귀하의 VM에?)이 UI를 업데이트하지 않으면 INotifyPropertyChanged 인터페이스를 구현해야합니다. –

+0

WatermarkTextBox는 또한 컨트롤에 Name을 바인딩하는 클래스가 구현하기 때문에'INotifyPropertyChanged'를 포함해야합니까? – Krowi

답변

1

WatermarkTextBox Binding에 문제가있는 것 같습니다. 그리드에 이름을 지정하고 당신이 당신의 제어에

 <Grid x:Name="grid"> 
     <TextBlock Margin="5 0 5 0" 

xaml.cs

public partial class WatermarkTextBox : UserControl 
{ 
    public WatermarkTextBox() 
    { 
     InitializeComponent(); 
     grid.DataContext = this; 
    } 
난이 도움이되기를 바랍니다 수있는 속성에 바인딩되기 때문에 그 자체를 UserControl을 위해 DataContext를 설정 .

업데이트 :

 <c:WatermarkTextBox Watermark="[Design] Name *" 
       Text="{Binding Name, Mode=TwoWay, FallbackValue='Name'}" /> 
+0

이것은 'Name'속성의 값을 표시하지 않는 문제를 수정합니다. 예를 들어, 속성을 "TestCompany"값으로 설정했습니다. "TestCompanyAgain"으로 변경하면 "TestCompany"가 반환됩니다. 왜 이런 일이 발생하는지 더 많은 코드가 필요합니까? – Krowi

+0

나는 그것과 그것의 일 벌금을 시험했다. – ethicallogics

+0

Notifying PropertyChanged 여부를 확인하십시오. – ethicallogics

관련 문제