2014-05-17 2 views
1

저는 WPF로 시작하기 때문에 로컬 변수와 레이블 간의 바인딩을 설정하려고합니다. Basicaly 로컬 변수가 변경되면 레이블을 업데이트하려고합니다. 솔루션을 찾고 있었지만 모두 텍스트 변수를 클래스 변수가 아닌 소스로 사용하고 있으며이 방법으로 작동하는지조차 모르겠습니다. 그래서 여기에 내 코드가있다.변수에 레이블 바인딩

public partial class MainWindow : Window 
{ 
    int idCounter; 

    public MainWindow() 
    { 
     InitializeComponent(); 


     Binding b = new Binding(); 
     b.Source = idCounter; 
     b.Mode = BindingMode.OneWay; 
     b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 

     myLabel.SetBinding(Label.ContentProperty,b); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     idCounter++; 
    } 
} 

버튼이 작동하지만, idCounter는 값을 변경하지만 라벨에 업데이트되지 않으므로 바인딩이 잘못되었습니다. 누군가가 잘못되었다고 말할 수 있습니까? 감사합니다

답변

4

당신이 당신의 클래스를 변경하는 경우 귀하의 코드가 작동합니다 이에 ...

public partial class Window1 : Window, INotifyPropertyChanged 
    { 
     private int _idCounter; 
     public int IdCounter 
     { 
      get { return _idCounter; } 
      set 
      { 
       if (value != _idCounter) 
       { 
        _idCounter = value; 
        OnPropertyChanged("IdCounter"); 
       } 
      } 
     } 
     public Window1() 
     { 
      InitializeComponent(); 
      myLabel.SetBinding(ContentProperty, new Binding("IdCounter")); 
      DataContext = this; 
     } 
     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      e.Handled = true; 
      IdCounter++; 
     } 
     #region INotifyPropertyChanged Implementation 
     public event PropertyChangedEventHandler PropertyChanged; 
     protected virtual void OnPropertyChanged(string name) 
     { 
      var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null); 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(name)); 
      } 
     } 
     #endregion 
    } 

당신이 가지고 있던 문제의 일부

...

창 자체가 INotifyPropertyChanged를 구현하여 바인딩 엔진이 귀를 처리 할 수 ​​있도록해야합니다.

IdCounter는 공용이어야하며 바인딩 엔진이이를 가져올 수 있도록 공개 게터가 있어야합니다.

IdCounter (이 경우 MainWindow)를 선언 한 모든 클래스에 DataContext를 설정해야합니다. 문제의 일부는 바인딩 엔진에 DataContext가 없다는 것입니다.

BindingMode 설정은 레이블이 기본적으로 해당 방식으로 바인딩되기 때문에 빨간색 청어입니다.

레이블의 내용에 원본 속성을 업데이트하는 메커니즘이 없으므로 UpdateSourceTrigger는 빨간색 청어입니다. 레이블의 내용은 사용자가 코드에서 알아야하는 내용을 입력 할 수있는 텍스트 상자와 다릅니다. 사용자가 변경할 수없는 항목에 바인딩하는 경우 UpdateSourceTrigger를 잊어 버리면 대상 속성이 중요합니다.

처리기가 이벤트를 표시해야합니다. 이는 좋은 습관이며 바인딩에 영향을주지 않습니다.

바인딩 생성자는 경로 만 있으면됩니다.

이 코드는 예상되는 결과를 제공합니다. 즉, 버튼이 클릭 될 때 라벨이 갱신된다는 것이다. 확인, 컴파일 및 vs2013, .net 4.5에서 실행.

다른 응답자는 당신이보기 모델을 사용해야한다고 말했습니다. 이 100 %에 동의하며 전체적으로 고려하는 것이 좋습니다.

+2

기술적으로 당신의 객체는 INotifyPropertyChange에서 상속받지 않습니다. 그들은 그것을 구현합니다. 그래도 좋은 대답. –

+1

@JohnathonSullinger, 기민한 머리가 와줘서 고마워. 내가 편집 할게. 고마워 –

2

INotifyPropertyChanged을 구현하는 것뿐만 아니라 속성을 사용하여 속성이 변경 될 때 label의 콘텐츠가 업데이트되도록하려는 경우입니다. 이상적 :

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:converters="clr-namespace:WpfApplication1" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <Label Width="200" Height="50" Content="{Binding MyLabel}"/> 
     <Button Height="30" Width="100" Content="Increment" Click="Button_Click" /> 
    </StackPanel> 
</Window> 

xaml.cs :

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     MainViewModel vm = new MainViewModel(); 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = vm; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      vm.MyLabel += 1; 
     } 
    } 
} 

MainViewModel.cs :

namespace WpfApplication1 
{ 
    public class MainViewModel : INotifyPropertyChanged 
    { 
     #region Members 
     private int _myLabel; 
     #endregion Members 

     #region Properties 
     public int MyLabel 
     { 
      get 
      { 
       return _myLabel; 
      } 
      set 
      { 
       _myLabel = value; 
       NotifyPropertyChanged("MyLabel"); 
      } 
     } 

     #endregion Properties 

     public MainViewModel() 
     { 
     } 

     #region INotifyPropertyChanged 
     public event PropertyChangedEventHandler PropertyChanged; 
     private void NotifyPropertyChanged(String propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     #endregion 
    } 
} 

참고

여기 간단한 ViewModel

XAML을 사용하는 예이다 당신 개인 또는 필드 그래서 공공 재산으로 변환 뭔가 대신 Click 이벤트 처리기

1
  1. 당신은 바인딩 할 수 없습니다의 Button에 대한 Command을 사용할 것입니다. 유효한 바인딩 소스가 무엇인지 알 수 있습니다. here
  2. UI로 변경 내용을 가져 오려면 INotifyPropertyChanged 인터페이스를 구현하고 속성 값이 변경 될 때마다 이벤트를 발생시켜야합니다. 그래서 idCounter이 같은 더 보일 것이다 :

    private int _idCounter; 
    
    public int idCounter 
    { 
        get { return _idCounter; } 
        set 
        { 
         if (_idCounter != value) 
         { 
          _idCounter = value; 
          OnPropertyChanged("idCounter"); 
         } 
        } 
    } 
    
  3. 당신이 속성에 바인딩을 만들 당신은 당신이 Path을하는 곳에서 지정해야하므로 문맥을 바인딩에 Path

  4. 바인딩 작업을 사용합니다. 가장 쉬운 방법은 DataContext으로 설정하는 것입니다. 귀하의 경우 초기화가 더 같이해야 그렇게 : @로

    Binding b = new Binding("idCounter"); 
    b.Mode = BindingMode.OneWay; 
    b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
    
    myLabel.SetBinding(Label.ContentProperty, b); 
    DataContext = this; 
    
  5. 을 그의 대답에 제안 d.moncada 당신은 전용 뷰 모델을 만들어야합니다

관련 문제