2009-04-03 4 views
19

Objective-c/cocoa는 컨트롤의 속성 (즉, 텍스트 상자의 텍스트)을 개체의 속성에 바인딩 할 수있는 바인딩 양식을 제공합니다. C# w/.Net 3.5에서이 기능을 복제하려고합니다.C#의 개체에 데이터 바인딩

나는 파일 MyClass.cs에 다음과 같은 매우 간단한 클래스를 만들었습니다

class MyClass 
{ 
    private string myName; 

    public string MyName 
    { 
     get 
     { 
      return myName; 
     } 

     set 
     { 
      myName = value; 
     } 
    } 

    public MyClass() 
    { 
     myName = "Allen"; 
    } 
} 

가 나는 또한 1 텍스트 박스 1 개 버튼으로 간단한 양식을 만들었습니다. 폼 코드 안에 Myclass의 인스턴스 하나를 초기화하고 프로젝트를 만들었습니다. Vs2008의 DataSource Wizard를 사용하여 개체를 기반으로 데이터 소스를 만들고 MyClass 어셈블리를 선택했습니다. 이것은 데이터 소스 개체를 만들었습니다. 나는이 데이터 소스로 텍스트 상자의 데이터 바인딩을 변경했다. 그러나 예상 된 결과 (텍스트 상자의 내용이 "allen")는 달성되지 않았습니다. 또한 텍스트를 텍스트 상자에 넣는 것은 개체의 이름 속성을 업데이트하지 않습니다.

나는 여기에 근본적인 것이 빠져 있다는 것을 알고있다. 어떤 시점에서 나는 폼 코드 내에서 텍스트 박스로 초기화 된 MyClass 클래스의 인스턴스를 묶어야하지만 발생하지 않았다. 내가 온라인에서 보았던 모든 것은 DataBinding을 객체와 함께 사용하여 광택을 보일 것입니다. 그래서 모든 도움이 정말 감사합니다.

편집 : 그 주석 경우

this.myClassBindingSource.DataSource = typeof(BindingTest.MyClass); 

및 대체 :

내가 답변에서 배운 것을 활용하여, 나는 비주얼 스튜디오에 의해 생성 된 코드를보고, 다음이 있었다

this.myClassBindingSource.DataSource = new MyClass(); 

예상되는 동작이 나타납니다. VS에서 생성 된 기본 코드는 왜 그런 것입니까? 이 방법이 작동하는 방법보다 정확하다고 가정하면 VS가 생성 한 범위 내에서 작동하도록 코드를 수정해야합니까?

+0

기본 코드는 디자인 타임에 모든 컨트롤이 데이터 바인딩에 사용할 수있는 다양한 유형의 속성을 알 수 있도록 처리됩니다. 하지만 런타임에는 실제 인스턴스가 필요합니다. 자동 생성 된 코드를 제거하지 말고 폼에서 새 값을 설정하십시오. –

답변

15

텍스트 상자의 데이터 소스를 새 데이터 소스로 지정해야합니다. 그러나 추가로, 데이터 소스의 데이터 소스를 클래스의 인스턴스로 지정해야합니다.

MyDataSource.DataSource = new MyClass(); 
TextBox1.DataSource = MyDataSource; 

첫 번째 단계에서 작동합니다. 다른 사람들이 언급했듯이, 백그라운드 프로세스를 통해 클래스 속성을 수정하려는 경우 클래스에 추가 인터페이스 (INotifyPropertyChanged 등)를 구현해야 할 수도 있습니다.

양식을 통해서만 속성을 업데이트하는 경우이 단계가 필요하지 않습니다. 속성 선언에 {; 세트에서 얻을 수

+3

TextBox1.DataBindings.Add ("Text",> Object <, "> PropertyName < "); –

12

당신은 MyClass의 유형에에서 INotifyPropertyChanged 인터페이스를 구현해야합니다

public class MyClass : INotifyPropertyChanged 
{ 
    private string _myName; 

    public string MyName 
    { 
     get { return _myName; } 
     set 
     { 
      if(_myName != value) 
      { 
       _myName = value; 
       OnPropertyChanged("MyName"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if(PropertyChanged != null) 
      PropertyChanged(this , new PropertyChangedEventArgs(propertyName)); 
    }  
} 

이 인터페이스는 데이터 바인딩 인프라가 필요합니다 당신은 간단한 데이터 바인딩을 지원합니다. INotifyPropertyChanged 인터페이스는 속성이 변경되었음을 '바인딩'에 알리는 데 사용되므로 DataBinding 인프라가 그에 따라 작동 할 수 있습니다.

그런 다음 MyName 속성을 텍스트 상자의 Text 속성에 데이터 바인딩 할 수 있습니다. 당신은 아마 당신의 MyName로 속성에 바인딩 속성을 필요로 (뿐만 아니라 프레데릭의 제안에 따라)처럼

0

가 보이는 :

[System.ComponentModel.Bindable(true)] 
    public string MyName 
    { 
     get { return _myName; } 
     set 
     { 
      if(_myName != value) 
      { 
       _myName = value; 
       OnPropertyChanged("MyName"); 
      } 
     } 
    } 

통해 : 나는 내 앞에 코드가없는 http://support.microsoft.com/kb/327413

0

을 하지만 데이터 소스는 컬렉션과 같은 것이라고 생각합니다. MyClass의 인스턴스를 데이터 소스에 추가해야합니다. 그러면 폼 필드가 바인딩됩니다. 데이터 소스를 통해 MyClass의 여러 인스턴스로 이동하는 방법도 있지만 필요에 따라 들리지는 않습니다. DataSource에 대한 문서를 확인하십시오.

멋진 인터페이스를 구현할 필요가 없다고 생각합니다. 일부 값을 변경 한 후에는 현재 항목을 새로 고치거나 다시 바인딩 할 수있는 데이터 소스에 메서드가 있다는 것을 기억하는 것 같습니다.

3

나는

이 당신이 명시 적으로 누락하고 아마도 때문이다 DataBinding.Add("TEXT", myObject, myObjectProperty) 방법에 오류 메시지가!

BAD :

public string FirstName; //<-- you will not be able to bind to this property! 

GOOD :

public string FirstName { get; set; } 
+0

public string FirstName; 필드를 정의하고, 필드에 바인딩 할 수는 없지만 "명시 적으로 선언 된 속성"이 아니기 때문이 아닙니다. "public string FirstName;"은 속성이 아님 , 특정 오류 메시지를 복사하여 붙여 넣을 수 있다면 누군가 검색하여 내 게시물을 찾을 수 있습니다. –

0
using System.Collections.Generic; 

public class SiteDataItem 
{ 
private string _text; 
private string _url; 
private int _id; 
private int _parentId; 

public string Text 
{ 
    get 
    { 
     return _text; 
    } 
    set 
    { 
     _text = value; 
    } 
} 

public string Url 
{ 
    get 
    { 
     return _url; 
    } 
    set 
    { 
     _url = value; 
    } 
} 
public int ID 
{ 
    get 
    { 
     return _id; 
    } 
    set 
    { 
     _id = value; 
    } 
} 
public int ParentID 
{ 
    get 
    { 
     return _parentId; 
    } 
    set 
    { 
     _parentId = value; 
    } 
} 
public SiteDataItem(int id, int parentId, string text, string url) 
{ 
    _id = id; 
    _parentId = parentId; 
    _text = text; 
    _url = url; 
} 

public static List<SiteDataItem> GetSiteData() 
{ 
    List<SiteDataItem> siteData = new List<SiteDataItem>(); 
    siteData.Add(new SiteDataItem(1, 0, "All Sites", "")); 
    siteData.Add(new SiteDataItem(2, 1, "Search Engines", "")); 
    siteData.Add(new SiteDataItem(3, 1, "News Sites", "")); 
    siteData.Add(new SiteDataItem(4, 2, "Yahoo", "http://www.yahoo.com")); 
    siteData.Add(new SiteDataItem(5, 2, "MSN", "http://www.msn.com")); 
    siteData.Add(new SiteDataItem(6, 2, "Google", "http://www.google.com")); 
    siteData.Add(new SiteDataItem(7, 3, "CNN", "http://www.cnn.com")); 
    siteData.Add(new SiteDataItem(8, 3, "BBC", "http://www.bbc.co.uk")); 
    siteData.Add(new SiteDataItem(9, 3, "FOX", "http://www.foxnews.com")); 
    return siteData; 
} 
} 

세부 사항은 더 당신이 튜토리얼 dapfor를 읽을 수 있습니다. com

관련 문제