2013-06-01 3 views
1

У меня есть DataGridView и список объектов, которые я хотел бы показать.Объекты привязки DataGridView C#

Объекты таковы:

public class Entity 
{ 
    public int ID { get; set; } 
}  

public class Travel: Entity 
{ 
    public Service Service { get; set; } 
    public City Source { get; set; } 
    public City Destiny { get; set; } 
    public decimal Price { get; set; } 
} 

public class Service: Entity 
{ 
    public string Name { get; set; } 
} 

public class City: Entity 
{ 
    public string Name { get; set; } // Max 50 chars 
} 

В моей форме я связать список Туристических объектов, как это:

List<Travel> travels = logic.GetAllTravels(); 
DgvRecorridos.DataSource = travels; 

И я получаю следующее:

enter image description here

Я хотел бы получить имя службы, источник города и судьбы C вместо этого.

Заранее спасибо.

ответ

2
List<Travel> travels = logic.GetAllTravels(); 
var _bind = from a in travels 
      select new 
      { 
       Servicename = a.Service.Name, 
       SourceName = a.Source.Name, 
       DestinyName = a.Destiny.Name, 
       Price = a.Price 
      }; 
DgvRecorridos.DataSource = _bind; 

или

List<Travel> travels = logic.GetAllTravels(); 
var _bind = travels.Select(a => new 
      { 
       Servicename = a.Service.Name, 
       SourceName = a.Source.Name, 
       DestinyName = a.Destiny.Name, 
       Price = a.Price 
      }); 
DgvRecorridos.DataSource = _bind; 
+0

Спасибо за ответ. Как изменить текст заголовка? – ehh

+0

@ehh Вы имеете в виду заголовок datagrid? Если да, вы можете изменить его в свойствах datagridview. –

+0

Да, спасибо. Мне было интересно, можно ли это сделать как часть анонимного метода. Вместо того, чтобы иметь Servicename для «Service Name» (или другого синтаксиса) – ehh

0

Ваш дизайн так странно. У меня есть другой подход, чтобы переопределить метод ToString() ваших классов (Service и города), как это:

public class Service: Entity 
{ 
    public string Name { get; set; } 
    public override string ToString(){ 
    return Name; 
    } 
} 

public class City: Entity 
{ 
    public string Name { get; set; } // Max 50 chars 
    public override string ToString(){ 
    return Name; 
    } 
} 

И что хорошо работает. Опять же, ваш дизайн немного странно^_^

2

Вместо того чтобы делать следующие коды ниже:

List<Travel> travels = logic.GetAllTravels(); 
DgvRecorridos.DataSource = travels; 

ли это:

List<Travel> travels = logic.GetAllTravels(); 
BindingSource bs = new BindingSource(); 
bs.DataSource = travels; 
DgvRecorridos.AutoGenerateColumn = false; 
DgvRecorridos.DataSource = bs; 

Затем добавьте столбцы вручную:

DataGridViewColumn col1 = new DataGridViewTextBoxColumn(); 
col1.DataPropertyName = "Service.Name"; 
col1.HeaderText = "Service Name"; 
dataGridView1.Columns.Add(col1); 

DataGridViewColumn col2 = new DataGridViewTextBoxColumn(); 
col2.DataPropertyName = "City.Name"; 
col2.HeaderText = "City Name"; 
dataGridView1.Columns.Add(col2); 

DataGridViewColumn col3 = new DataGridViewTextBoxColumn(); 
col3.DataPropertyName = "City.Name"; 
col3.HeaderText = "Destiny Name"; 
dataGridView1.Columns.Add(col3); 

DataGridViewColumn col4 = new DataGridViewTextBoxColumn(); 
col4.DataPropertyName = "Price"; 
col4.HeaderText = "Price"; 
dataGridView1.Columns.Add(col4); 

Затем добавьте обработчик событий форматирования ячейки для DataGridView:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    if (dataGridView1.Rows[e.RowIndex].DataBoundItem != null && 
     dataGridView1.Columns[e.ColumnIndex].DataPropertyName.Contains(".")) 
    { 
     e.Value = BindProperty(dataGridView1.Rows[e.RowIndex].DataBoundItem, 
      dataGridView1.Columns[e.ColumnIndex].DataPropertyName); 
    } 
} 

private string BindProperty(object property, string propertyName) 
{ 
    string retValue = ""; 

    if (propertyName.Contains(".")) 
    { 
     PropertyInfo[] arrayProperties; 
     string leftPropertyName; 

     leftPropertyName = propertyName.Substring(0, propertyName.IndexOf(".")); 
     arrayProperties = property.GetType().GetProperties(); 

     foreach (PropertyInfo propertyInfo in arrayProperties) 
     { 
      if (propertyInfo.Name == leftPropertyName) 
      { 
       retValue = BindProperty(propertyInfo.GetValue(property, null), 
       propertyName.Substring(propertyName.IndexOf(".") + 1)); 
       break; 
      } 
     } 
    } 
    else 
    { 
     Type propertyType; 
     PropertyInfo propertyInfo; 

     propertyType = property.GetType(); 
     propertyInfo = propertyType.GetProperty(propertyName); 
     retValue = propertyInfo.GetValue(property, null).ToString(); 
    } 

    return retValue; 
} 

Для полного руководства по форматированию ячейки, просматривать here на блоге Антонио Bello, это то, где я получил идею.^_^ Я также спросил здесь о том же вопросе два дня назад и получил те же ответы, что и вы, и я знаю, что это не то, что вы тоже хотите делать. Надеюсь, это поможет вам.

0

Весь этот код в методах CellFormatting и BindProperty кажется чрезмерным. Я имею в виду, что-то нужно в основном делать, но я думаю, что это уже сделано. Я реализую INotifyPropertyChanged в объекте, который я хочу привязать к строке сетки, и я помещаю эти объекты в BindingList. BindingList напрямую используется в качестве источника данных для сетки.

Этот подход означает немного больше ввода в основной класс сущности, который вы сопоставляете с сеткой, но я думаю, что он сохраняет намного больше в другом месте. Для реализации INotifyPropertyChanged в своем классе:

public class Entity: INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 
     public Entity() 
     { 
      Selected = false; 
     } 

     private bool _selected; 
     public bool Selected 
     { 
      get 
      { 
       return _selected; 
      } 
      set 
      { 
       if (_selected != value) 
       { 
        _selected = value; 
        OnPropertyChanged(nameof(Selected)); 
       } 
      } 
     } 

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

Затем поместите колонку в сетке и дать ему DataPropertyName из «Selected», чтобы соответствовать имя свойства в Entity, которая должна появиться в этом столбце. Очевидно, добавьте все свойства, которые вы хотите использовать в своей сетке, соответствующие свойствам объекта.Ключ состоит в том, чтобы реализовать средство настройки свойств с вызовом PropertyChanged.

Это дает вам двухстороннюю привязку между сеткой и вашим списком объектов.

Мое личное мнение: даже это слишком много кода. Я постоянно нахожу себе такие вещи, которые делают очевидное: возьмите свойство по имени и сопоставьте его с чем-то другим, которое знает это имя (например, столбец сетки в этом примере). Я просто не понимаю, почему эти вещи не просто автоматически подключаются. Список и сетка должны иметь достаточный смысл для определения этой базовой схемы самостоятельно. нулевые строки кода. Хорошо, одна строка кода. Grid.Datasource = Список. Так вот как я это делаю. Мне бы хотелось узнать меньше путей кода, чтобы сделать это.

Смежные вопросы