Привязка данных к объекту в C # - PullRequest
19 голосов
/ 03 апреля 2009

Objective-c / cocoa предлагает форму привязки, в которой свойства элемента управления (т. Е. Текст в текстовом поле) могут быть связаны со свойством объекта. Я пытаюсь продублировать эту функциональность в C # w / .Net 3.5.

Я создал следующий очень простой класс в файле MyClass.cs:

class MyClass
{
    private string myName;

    public string MyName
    {
        get
        {
            return myName;
        }

        set
        {
            myName = value;
        }
    }

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

Я также создал простую форму с 1 текстовым полем и 1 кнопкой. Я инициализировал один экземпляр Myclass внутри кода формы и создал проект. Используя мастер источников данных в Vs2008, я решил создать источник данных на основе объекта и выбрал сборку MyClass. Это создало сущность источника данных. Я изменил привязку данных текстового поля к этому источнику данных; однако ожидаемый результат (что содержимое текстового поля было бы "allen") не был достигнут. Кроме того, помещение текста в текстовое поле не приводит к обновлению свойства имени объекта.

Я знаю, что мне здесь не хватает чего-то фундаментального. В какой-то момент мне нужно было привязать мой экземпляр класса MyClass, который я инициализировал внутри кода формы, к текстовому полю, но этого не произошло. Все, на что я смотрел в Интернете, похоже, затушевывает использование DataBinding с объектом (или я полностью теряю оценку), поэтому любая помощь очень ценится.

Edit:

Используя то, что я узнал из ответов, я посмотрел на код, сгенерированный Visual Studio, в нем было следующее:

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

если я закомментирую это и подставлю:

this.myClassBindingSource.DataSource = new MyClass();

Я получаю ожидаемое поведение. Почему код по умолчанию генерируется VS, как это? Предполагая, что это более правильно, чем метод, который работает, как мне изменить мой код, чтобы он работал в рамках того, что генерирует VS?

Ответы [ 6 ]

15 голосов
/ 04 апреля 2009

Вы должны назначить источник данных текстового поля в качестве вашего нового источника данных. Но кроме того, вы должны назначить источник данных источника данных как экземпляр вашего класса.

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

Это должно сработать для вашего первого прохода. Как уже упоминалось, вам может понадобиться реализовать дополнительные интерфейсы для вашего класса (INotifyPropertyChanged и т. Д.), Если вы собираетесь изменять свойства класса с помощью каких-либо фоновых процессов.

Если вы обновляете свойства только через форму, этот шаг вам не нужен.

12 голосов
/ 03 апреля 2009

Вы должны реализовать интерфейс INotifyPropertyChanged для вашего типа MyClass:

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) );
   }       
}

Этот интерфейс необходим для инфраструктуры DataBinding, если вы хотите поддерживать простую привязку данных. Интерфейс INotifyPropertyChanged используется для уведомления «привязки» об изменении свойства, поэтому инфраструктура DataBinding может действовать в соответствии с ним.

Затем вы можете привязать свойство MyName к свойству Text текстового поля.

3 голосов
/ 13 апреля 2010

Я получаю сообщение об ошибке в методе DataBinding.Add("TEXT", myObject, myObjectProperty)

Это, вероятно, потому что вы пропустили явное {get; set;} в объявлении свойства!

ПЛОХО:

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

GOOD

public string FirstName { get; set; }
0 голосов
/ 17 ноября 2012
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. ком

0 голосов
/ 04 апреля 2009

У меня нет никакого кода передо мной, но я думаю, что источник данных подобен коллекции. Вы должны добавить экземпляр MyClass к источнику данных, и это то, к чему будут привязаны поля формы. Существуют также методы для навигации по источнику данных к нескольким экземплярам MyClass, но, похоже, вам это не нужно. Проверьте документы на источник данных.

Не думаю, что вам нужно реализовывать какие-либо модные интерфейсы. Кажется, я помню, что в источнике данных есть метод, который позволяет обновлять или перепривязывать текущий элемент после изменения некоторых значений.

0 голосов
/ 04 апреля 2009

Похоже, вам, вероятно, нужен атрибут Bindable в свойстве MyName (и также следуйте совету Фредерика):

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

Через: http://support.microsoft.com/kb/327413

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...