2008-09-23 3 views
17

다음 개체 인 Car를 gridview에 바인딩하는 방법은 무엇입니까?복합 유형 속성을 DataGrid에 바인딩 할 수 있습니까?

 
public class Car 
{ 
    long Id {get; set;} 
    Manufacturer Maker {get; set;} 
} 

public class Manufacturer 
{ 
    long Id {get; set;} 
    String Name {get; set;} 
} 

프리미티브 유형은 쉽게 바인딩되지만 Maker에 표시 할 방법이 없습니다. Manufacturer.Name을 표시하고 싶습니다. 심지어 가능할까요?

어떻게해야할까요? 나는 ManufacturerId를 Car에 저장 한 다음 Manufacturers 목록과 함께 lookupEditRepository를 설정해야합니까?

답변

5
public class Manufacturer 
    { 
     long Id {get; set;} 
     String Name {get; set;} 

     public override string ToString() 
     { 
      return Name; 
     } 
    } 

to 문자열 메서드를 재정의합니다.

+0

+1 이것이 단순한 물체에 대한 확실한 해결책이라고 생각합니다. – karlipoppins

+0

하나의 속성 만 있으면 좋겠지 만, 해당 물체의 배수 속성을 원한다면 작동하지 않습니다. –

12

예, 중첩 바인딩을 수행하려면 TypeDescriptionProvider를 만들 수 있습니다.

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx

+1

이것을 달성하는 복잡성 수준은 꽤 높습니다. 내가 비즈니스 오브젝트를 아마 변환 할 수있는 또 다른 바인드 가능 클래스 세트가 있어야합니까? – Xerx

+0

디자인 결정입니다. 어느 쪽이든 당신은 바인딩 목적을 위해 단순히 새로운 종류의 낱단을 창조하거나 나의 포스트에서 제공되는 조리법을 사용해야한다. 개인적으로, 나는 '도우미'로 클래스 계층 구조를 어지럽히는 것을 싫어하므로 후자와 함께 갈 것입니다. –

+0

+1 기사는 내가 필요한 것입니다 ... – takrl

2

는 그냥 목록을 사용하여 문자열 "Maker.Name"에 DataMember를을 설정하고 원하는 경우 DataKeyField 자동차의 ID를 바로 사용하기 : 다음은 MSDN 블로그에서 자세한 예이다 "ID"로 설정하십시오. 적어도, 중계기 제어 작동

dataGrid.DataSource = carList; 
dataGrid.DataMember = "Maker.Name"; 
dataGrid.DataKeyField = "ID"; 
dataGrid.DataBind(); 

알아요 ...

7

내가 최근 응용 프로그램이 접근 방법은 내 자신의 DataGridViewColumn 및 DataGridViewCell 클래스 중 하나 떨어져 상속 만드는 것이 었습니다 DataGridViewTextBoxColumn 및 DataGridViewTextBoxCell과 같은 기존 항목

원하는 셀 유형에 따라 Button, Checkbox, ComboBox 등을 사용할 수 있습니다. System.Windows.Forms에서 사용할 수있는 유형을 살펴보십시오.

셀은 값을 객체로 처리하므로 Car 클래스를 셀 값에 전달할 수 있습니다.

SetValue 및 GetValue를 재정의하면 값을 처리하는 데 필요한 추가 논리를 가질 수 있습니다. 예를 들어

: 당신이해야 할 중요한 것은 당신의 사용자 정의 셀 클래스에 CellTemplate 설정되어 열 클래스에

public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell 
{ 
    protected override object GetValue(int rowIndex) 
    { 
     Car car = base.GetValue(rowIndex) as Car; 
     if (car != null) 
     { 
      return car.Maker.Name; 
     } 
     else 
     { 
      return ""; 
     } 
    } 
} 

.

public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn 
{ 
    public CarColumn(): base() 
    { 
     CarCell c = new CarCell(); 
     base.CellTemplate = c; 
    } 
} 

DataGridView에서 이러한 사용자 지정 열/셀을 사용하면 DataGridView에 많은 추가 기능을 추가 할 수 있습니다.

GetFormattedValue를 재정 의하여 문자열 값에 사용자 지정 서식을 적용하여 표시된 서식을 변경하는 데 사용했습니다.

또한 그림판에서 재정의를 수행하여 가치 조건에 따라 사용자 지정 셀 강조 표시를 수행하고 값에 따라 원하는대로 셀 Style.BackColor를 변경했습니다.

2

바인딩 대상으로 특정 중첩 속성을 표시하려면 Ben Hoffstein의 답변 (http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx)이 좋습니다. 참조 된 기사는 다소 둔감하지만 작동합니다.

열을 복잡한 속성 (예 : 제조업체)에 바인딩하고 렌더링 논리를 무시하려는 경우 ManiacXZ에서 권장하는 작업을 수행하거나 BoundField를 하위 클래스로 만들고 FormatDataValue()의 사용자 지정 구현을 제공하십시오. 이는 ToString()을 재정의하는 것과 유사합니다. 객체 참조를 얻고 그리드에 표시 할 문자열을 반환합니다. 이 같은

뭔가 :

public class ManufacturerField : BoundField 
{ 
    protected override string FormatDataValue(object dataValue, bool encode) 
    { 
     var mfr = dataValue as Manufacturer; 

     if (mfr != null) 
     { 
      return mfr.Name + " (ID " + mfr.Id + ")"; 
     } 
     else 
     { 
      return base.FormatDataValue(dataValue, encode); 
     } 
    } 
} 

그냥 데이터 필드로 "제조"를 지정 그리드에 ManufacturerField을 추가하고 갈 수 있어요.

public class Car 
{ 
    public long Id {get; set;} 
    public Manufacturer Maker {private get; set;} 

    public string ManufacturerName 
    { 
     get { return Maker != null ? Maker.Name : ""; } 
    } 
} 

public class Manufacturer 
{ 
    long Id {get; set;} 
    String Name {get; set;} 
} 
+0

+1 링크 된 기사가 정확히 내가 필요한 것입니다. – takrl

1

난 당신이 다음을 할 수있는 가정 것이다

<asp:TemplateColumn 
    HeaderText="Maker"> 
    <ItemTemplate> 
      <%#Eval("Maker.Name")%> 
    </ItemTemplate> 
</asp:TemplateColumn> 

는 ASP.NET 4.0 특정 될 수 있지만, 마치 마법처럼 작동합니다!

+1

사람들이 일반적으로하고 싶어하는 것은 아니지만 Demeter의 법칙에 대해 더 많이 짐작하는 것처럼 보입니다. – jpierson

2

여기가 작동있어 또 다른 옵션은 다음과 같습니다 :

22

Allright guys ...이 질문은 게시되었습니다.하지만 꽤 좋은 & 중첩 된 속성을 검색하기 위해 cell_formatting 이벤트에서 리플렉션을 사용하여이 작업을 수행하는 간단한 방법을 발견했습니다.

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
    { 

     DataGridView grid = (DataGridView)sender; 
     DataGridViewRow row = grid.Rows[e.RowIndex]; 
     DataGridViewColumn col = grid.Columns[e.ColumnIndex]; 
     if (row.DataBoundItem != null && col.DataPropertyName.Contains(".")) 
     { 
      string[] props = col.DataPropertyName.Split('.'); 
      PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]); 
      object val = propInfo.GetValue(row.DataBoundItem, null); 
      for (int i = 1; i < props.Length; i++) 
      { 
       propInfo = val.GetType().GetProperty(props[i]); 
       val = propInfo.GetValue(val, null); 
      } 
      e.Value = val; 
     } 
    } 

을 그리고 그것 뿐이다 :

은 다음과 같이 간다! 열의 DataPropertyName에서 익숙한 "ParentProp.ChildProp.GrandChildProp"구문을 사용할 수 있습니다.

+0

잘 했어! 공유해 주셔서 감사합니다. – Amir

+0

아주 좋은, 고마워요 ^^ – Mahmoud

+0

이것은 더 upvotes 자격이! 무슨 일이 벌어지고 있는지 모르지만 롤은 작동합니다. 공유 주셔서 감사합니다! –

관련 문제