2011-07-05 7 views
1

내 상사는 코드 작성을 위해 매우 특이한 시나리오를 발명하기를 좋아하는데,이 하나가 저를 곤혹스럽게합니다. 나는 매우 늦은 바운드 데이터를 표시하기 위해 GridView를 사용해야하는 WPF 응용 프로그램을 만들고 있습니다. 데이터를 표시하기 위해 그는 일부 열 머리글을 사용하여 GridView를 처음 초기화 할 수 있기를 원합니다. 이는 문제가되지 않습니다. 그런 다음 GridView, DataTable 및 일부 서식 지정 정보를 데이터를 바인딩하는 메서드에 전달해야합니다.WPF에서 동적으로 생성 된 GridView 바인딩

디자인 타임에는 바인딩 할 DataTable의 열을 알 수 없습니다. 전체 표가 동적으로 만들어 지므로 XAML을 사용할 수 없습니다. 데이터를 바인딩 할 때마다 열 단위 서식 지정 데이터를 지정해야합니다. 필자는 형식 생성 클래스를 생성자의 매개 변수로 사용하는 IValueConverter 구현을 구현했습니다. 마지막으로 다른 방법으로 서식이 지정된 동일한 열을 데이터 테이블에 여러 번 표시하는 것을 지원해야한다는 점이 다릅니다. 분명히 이름 충돌이 있기 때문에 하나의 DataTable에 여러 개의 복사본을 가질 수는 없습니다.

는 여기에 지금까지이 작업은 다음과 같습니다

/// <summary> 
    /// Sets the view of the passed ListView to a new GridView with properly formatted headers. 
    /// The headers are also the field names (column names) of the data table that you will 
    /// bind to 
    /// </summary> 
    /// <param name="displayPanel"></param> 
    /// <param name="displayFieldList"></param> 
    public static void InitializeGrid(ListView displayPanel,IDisplayFieldList displayFieldList) 
    { 


     GridView gv = new GridView(); 
     gv.AllowsColumnReorder = true; 

     for (int i = 0; i < displayFieldList.Count; i++) 
     { 
      GridViewColumn col = new GridViewColumn(); 
      col.Header = displayFieldList[i].HeaderText; 

      gv.Columns.Add(col); 
     } 

     displayPanel.View = gv; 
    } 

    /// <summary> 
    /// Binds data to the columns set in the ListView.View. Displays and formats the data. 
    /// </summary> 
    /// <param name="displayPanel"></param> 
    /// <param name="table"></param> 
    /// <param name="displayFieldList"></param> 
    public static void BindData(ListView displayPanel, DataTable table, IDisplayFieldList displayFieldList) 
    { 
     for(int i=0; i<displayFieldList.Count; i++) 
     { 
      GridViewColumn gridCol = ((GridView)displayPanel.View).Columns[i]; 

      DmlDisplayField displayField = displayFieldList[i] as DmlDisplayField; 
      if(displayField != null) 
      { 
       gridCol.DisplayMemberBinding = new Binding() 
       { 
        Source = table.Columns[displayField.DataField], 
        Converter = new MaskConverter(displayField.DataField), 
        ConverterParameter = displayField 
       }; 
      } 
      else 
      { 
       gridCol.DisplayMemberBinding = new Binding() 
       { 
        Source = table.Columns[displayFieldList[i].Name] 
       }; 
      } 
     } 
     displayPanel.ItemsSource = table.AsDataView(); 
    } 

IDisplayFieldList 메타 데이터를 포함 DisplayField 또는 DmlDisplayField 클래스의 모음입니다. MaskConverter는 다양한 방법으로 DmlDisplayField 열의 서식을 지정하는 IValueConverter입니다.

이 코드를 실행하면 모든 행이 비어 있지만 개별 행을 선택할 수 있습니다.

지금까지 여러 바인딩 방법을 시도해 봤지만 System.Reflection에서 "모호한 일치 예외"를 많이 사용했습니다.

당신이 MaskConverter를 게시 할 날 필요로하면, 내가하지만 꽤 혼란의 ...

어떤 아이디어가? 엄청 고마워!

은 ICustomTypeDescriptor 인터페이스가 제공 할 수 있습니다 ...

답변

0

난 단지 윈폼에있는 DataGridView와 비슷한 일을했습니다,하지만 난 WPF의의 GridView는 자동으로 생성하는 즉시 그 열을 할 수 있어야한다고 생각하여 그리드에 PropertyDescriptors 자신의 집합. 같은 속성 (열거 자/설명자)에 두 개의 열을 바인딩 할 필요가 없습니다. 동일한 속성/열/필드/모두에 대해 두 개의 고유 한 속성 설명자를 제공 할 수 있기 때문에 ...

반면에이 개념은 과잉 될 수 있습니다 이 작업을 수행하는 더 쉬운 방법이있을 수 있으므로 제안 사항 일뿐입니다.

관련 문제