2012-03-12 3 views
2

텍스트 상자 값이 변경되면 추가 단추를 사용할 수있게 구현하려고합니다.양방향 바인딩 문제 - PropertyChanged & CanExecuteChanged

나는 뷰 모델에 텍스트 상자를 바인딩 :

<TextBox Name="nameTbx" Text="{Binding Path=NewNode.Name, Mode=TwoWay}" /> 

내 버튼 :

<Button Content="Add" Command="{Binding Path=AddNewNodeProperty}"/> 

을 XAML 코드에서 난 내 뷰 모델에 DataContext를 설정 뒤에.

public class AddNode : ICommand 
{ 
    private ServiceMapViewModel viewModel; 

    public AddNode(ServiceMapViewModel viewModel) 
    { 
     this.viewModel = viewModel; 
     this.viewModel.PropertyChanged += (s, e) => 
     { 
      if (CanExecuteChanged != null) 
      { 
       CanExecuteChanged(this, new EventArgs()); 
      } 
     }; 
    } 

    public bool CanExecute(object parameter) 
    { 
     bool b = !string.IsNullOrWhiteSpace(this.viewModel.NewNode.Name); 

     return b; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     this.viewModel.AddNewNode(); 
    } 
} 

그리고 마지막으로 내 노드 클래스 :

public class Node 
{ 
    public string Name { get; set; } 

    public bool? IsChecked { get; set; } 

    public Group Group { get; set; } 

    public Category Category { get; set; } 

    public string Metadata { get; set; } 

    public List<string> Children = new List<string>(); 

    public List<string> Parents = new List<string>(); 
} 
내가 _addNewNodeProperty 여기

this._addNewNodeProperty = new AddNode(this); 

내 ADDNODE 클래스를 초기화 생성자에서

/* code*/ 

private Node _newNode = new Node(); 
public Node NewNode 
{ 
    get 
    { 
     return _newNode; 
    } 
    set 
    { 
     _newNode = value; 
     OnPropertyChanged("NewNode"); 
    } 
} 

private AddNode _addNewNodeProperty; 
    public AddNode AddNewNodeProperty 
    { 
     get 
     { 
      return _addNewNodeProperty; 
     } 
    } 

: 같은 뷰 모델 본다

프로 블 림은 텍스트 상자 텍스트를 변경할 때 NewNode가 값을 받고 있지만 설정해야한다는 것입니다.

고급 Tnx!

편집 내가 뭔가를 추가하자 :

나는 또한 화면에 데이터 그리드 및 선택 항목이 변경 될 때, 내 추가 사용할 수있게 butom 있습니다.

선택 항목 :

<DataGrid Name="nodeDataGrid" ItemsSource="{Binding Path=MyServiceMap.Nodes}" 
     Background="Silver" Margin="0,34,10,10" IsReadOnly="True" SelectedItem="{Binding Path=SelectedNode}" > 

그리고 VM :

private Node _selectedNode = new Node(); 
    public Node SelectedNode 
    { 
     get 
     { 
      return _selectedNode; 
     } 
     set 
     { 
      _selectedNode = value; 
      OnPropertyChanged("SelectedNode"); 
     } 
    } 

답변

1

귀하의 텍스트 상자는 당신의 Node 개체의 Name 속성에 바인딩됩니다. Name 속성은 변경 될 때 PropertyChanged 이벤트를 발생시키지 않습니다. 이벤트가 변경되면 전체 NewNode 속성 만 이벤트를 발생시킵니다.

편집 제안 mtaboy 같이 INotifyPropertyChanged 인터페이스를 구현하는 것이하는 NodeViewModel 클래스를 생성하는 것입니다 제안을

한 가지 방법을 제공합니다. ViewModel에서 사용자에게 공개하려는 모든 속성을 만들 수 있습니다. 모델 (예 : Node 클래스)과보기 (사용자에게 표시되는 UI) 사이에 ViewModel이 있다고 생각할 수 있습니다.

ICommand 로직을 자체 클래스로 캡슐화하는 것이 좋습니다. 자주 사용하는 것은 MSDN의 Josh Smith의 MVVM article에서 찾을 수있는 RelayCommand 클래스입니다. 이 클래스를 사용하는 경우 ViewModel 클래스에서 사용자가 추가 할 수 있는지 여부를 반환하는 속성 또는 개인 메서드를 정의 할 수 있습니다. 예를 들어,

private bool CanAddNewNode() 
{ 
    return !String.IsNullOrWhitespace(Name); 
} 

당신의 RelayCommand를 인스턴스화

, 당신은 위의 메소드를 참조하는 두 번째 매개 변수에 대한 람다를 전달할 수 있습니다.

var saveCommand = new RelayCommand(param => SaveMethod(), param => CanAddNewNode()); 

당신은 RelayCommand 객체를 반환 당신의 ViewModel에서 ICommand 속성을 노출합니다.

바라건대, 당신이 시작하게되기를 바랍니다.

+0

무엇을 제안합니까? :) – Bip

+0

몇 가지 구체적인 제안을 제공하기 위해 내 대답이 업데이트되었습니다. –

1

문제는 내가 내 텍스트 상자의 텍스트를 변경하는 경우, NewNode이 나에 대한 값을 받고 있지만,가되어 있다는 것입니다 세트

나는 Node 클래스에 대해서도 INotifyPropertyChanged 인터페이스를 지원해야한다고 생각합니다.

또한 각 캐릭터 업데이트 중에 ProEPRty를 동기화하려면 UpdateSourceTrigger를 설정하십시오. 그렇지 않으면 LostFocus 이벤트에서 속성이 업데이트됩니다.

<TextBox Name="nameTbx" 
     Text="{Binding Path=NewNode.Name, 
         Mode=TwoWay, 
         UpdateSourceTrigger=PropertyChanged}" /> 
+0

가 작동하지 않습니다 ... – Bip

+0

죄송합니다 그냥 완료 대답 – sll

+0

를 참조하십시오

public class Node:INotifyPropertyChanged { #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion string _name ; public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } } ..... 

을에서 INotifyPropertyChanged Impliment해야 하지만 난 WCF를 통해 .XML에서 데이터를 읽고 오전 및 구현할 때 .XML에서 모든 데이터를 얻을 수 없습니다. INotifyPropertyChanged. – Bip

1

노드 클래스, 더 많은 정보가 나는 것을 시도 MVVM Pattern

+0

그걸 시도했지만 WCF를 통해 .XML에서 데이터를 읽고 INotifyPropertyChanged를 구현할 때 .XML에서 데이터를 가져올 수 없습니다. – Bip

+0

mvvm의 implments obseverpattern에 대해 INotifyPropertyChanged를 구현해야하지만 기사 http://www.codeproject.com/Articles/87510/WCF-by-Example-Introduction –

+0

말 그대로'클래스 노드 : INotifyPropertyChanged' - 이것은 상속이 아닙니다. 이것은 인터페이스 구현입니다. – sll

관련 문제