2011-02-18 8 views
3

저는 WPF에 익숙하지 않아 간단한 작업이 될 것이라고 생각했습니다. 즉, 프로그램 중에 변경되는 비즈니스 개체의 필드 값을 표시해야합니다. C#에서 TextBox.Text 속성을 수동으로 변경하여 "강제로"강제하는 방법을 알고 있지만 WPF를 배우면서 "올바르게"수행하려고합니다. 즉 데이터 바인딩을 의미합니다.WPF 종속 속성 질문

질문 # 1 : 내가 아는 한, 내 선택은 DependencyProperty를 사용하거나 비즈니스 개체에 INotifyPropertyChanged를 구현하는 것입니다.

질문 # 2 : 여기 내 코드의 제네릭 버전으로 DependencyProperty 경로로 이동하려고 시도했습니다.

마크 업 :

Button x:Name="nextButton" Content="Click" Grid.Row="2" Click="nextButton_Click" /> 
TextBox x:Name="myTextBox" Grid.Row="1" Text="{Binding Source=myTest, Path=Name, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>

코드 숨김 : 나는이 프로그램을 실행하면 아무것도 바인딩 속성 값에도 불구하고, 텍스트 상자에 나타납니다

namespace DependencyTest2 
{ 
    /// 
    /// Interaction logic for MainWindow.xaml 
    /// 
    public partial class MainWindow : Window 
    { 
     private int i; 

     private TestSphere myTest; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      i = 0; 

      myTest = new TestSphere(); 
     } 

     private void nextButton_Click(object sender, RoutedEventArgs e) 
     { 
      switch (i) 
      { 
       case 0: 
        myTest.Name = "string1"; 
        break; 
       case 1: 
        myTest.Name = "string2"; 
        break; 
       case 2: 
        myTest.Name = "string3"; 
        break; 
      } 

      i++; 
     } 
    } 

    class TestSphere : DependencyObject 
    { 

     public string Name 
     { 
      get { return (string)GetValue(NameProperty); } 
      set { SetValue(NameProperty, value); } 
     } 

     public static readonly DependencyProperty NameProperty = 
      DependencyProperty.Register("Name", typeof(string), typeof(TestSphere)); 


     public TestSphere() 
     { 
      Name = "default"; 
     } 
    } 
} 

은 - 뭔가 나는 다른이 원본 값이 변경되었음을 바인딩에 알리는 작업을 수행해야합니까? DependencyProperty를 소스로 사용한다고 생각했지만, 다시 WPF 신인입니다. 감사! 여기


    class TestSphere : NotifyProperyChangedBase 
    { 
     private string _Name; 

     public string Name 
     { 
      get { return _Name; } 
      set 
      { 
       this.CheckPropertyChanged("Name", ref _Name, ref value); 
      } 
     } 

     public TestSphere() 
     { 
      Name = "default"; 
     } 
    } 

    public abstract class NotifyProperyChangedBase : INotifyPropertyChanged 
    { 
     #region INotifyPropertyChanged Members 
     public event PropertyChangedEventHandler PropertyChanged; 
     #endregion 
     #region methods 
     protected bool CheckPropertyChanged(string propertyName, ref T oldValue, ref T newValue) 
     { 
      if (oldValue == null && newValue == null) 
      { 
       return false; 
      } 

      if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue)) 
      { 
       oldValue = newValue; 
       FirePropertyChanged(propertyName); 
       return true; 
      } 

      return false; 
     } 

     protected void FirePropertyChanged(string propertyName) 
     { 
      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     #endregion 

너무 내 새로운 마크 업입니다 :

  • 스티브는

좋아, 나는 다음과 같이 내가 CodeProject의 발견 래퍼 클래스를 사용에서 INotifyPropertyChanged를 구현하기 위해 노력


    Grid Name="myGrid"> 
     Grid.RowDefinitions> 
      RowDefinition Height="30"/> 
      RowDefinition Height="30"/> 
      RowDefinition Height="30"/> 
      RowDefinition Height="*"/> 
     /Grid.RowDefinitions> 
     Label x:Name="myLabel" Grid.Row="0" Foreground="Black" /> 
     Button x:Name="nextButton" Content="Click" Grid.Row="2" Click="nextButton_Click" /> 
     TextBox x:Name="myTextBox" Grid.Row="1" Text="{Binding Path=myTest.Name}"/> 
    /Grid> 

또한 'public MainWi'에 myGrid.DataContext = myTest; 행을 추가했습니다. myTest를 인스턴스화 한 직후에 ndow()를 호출합니다. 결과 프로그램을 단계별로 실행하면 this.PropertyChanged 값은 항상 null으로 평가되므로 PropertyChanged가 실행되지 않습니다. 정말로 멍청한 질문 일 것임에 틀림없는 것을 미리 미안.

  • 스티브
+0

업데이트마다 tyChanged()도 두 번. –

+0

둘째, 귀하의 {바인딩}이 어떻게 보이는지 보여 줄 수 있습니까? TextBox의 부모 컨테이너가 이고 myGrid.DataContext = myTest 인 경우 바인딩은 이제 {Binding Path = Name}이됩니다. –

+0

잡는 것에 감사드립니다! 원본으로 다시 되돌려 놓는 것을 잊었습니다. 위의 편집을 참조하십시오. – seveland

답변

1

당신 만 TestSphere 클래스하지 DependencyObject에 대해 INotifyPropertyChanged를 구현해야한다. 값을 업데이트 할 때 PropertyChanged(this, new PropertyChangedEventArgs("Name"))으로 전화하십시오.

둘째, 코드 숨김에서 해당 창에 대한 DataContext를 설정해야합니다. 그런 다음에 코드 숨김, 당신이 할 거라고

<Grid Name="MainForm"> 

: 루트 격자 요소에 대한 귀하의 XAML이 사용 말할 수

마지막으로
MainForm.DataContext = this; 

, public에 MYTEST 속성을 변경을, 그리고 당신의 XAML에서 바인딩 만해야한다

Text="{Binding Path=myTest.Name}" 
당신은 아마 NotifyPropertyChangedBase에/오래된 새 값을 비교하여 어떤 성능 향상을 볼 수 없습니다,하지만 당신은 FireProper를 호출하는 것처럼 여담으로, 보이는
+0

빠른 응답을 주셔서 감사합니다 - 내 원래 게시물을 편집하여 귀하의 제안에서 나온 새로운 질문을 추가하십시오. 다시 한 번 감사드립니다! – seveland