2012-04-25 77 views
1

我正在用c#創建一個應用程序,silverlight。我想弄清楚如何在自動生成後對我的數據網格中的列進行重新排序。在C#/ Silverlight程序中自動生成列自動記錄列

我試圖做這樣的事情:

private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     switch (e.PropertyName) 
     { 
      case "taskName": 
       { 
        e.Column.DisplayIndex = 0; 
        break; 
       } 
      case "overallPercentComplete": 
       { 
        e.Column.DisplayIndex = 1; 
        break; 
       } 
      case "TDO_ID": 
       { 
        e.Column.DisplayIndex = 2; 
        break; 
       } 
      case "WBS_ID": 
       { 
        e.Column.DisplayIndex = 3; 
        break; 
       } 
      case "baseLineSD": 
       { 
        e.Column.DisplayIndex = 4; 
        break; 
       } 
      case "baseLineEd": 
       { 
        e.Column.DisplayIndex = 5; 
        break; 
       } 
      case "estimatedSD": 
       { 
        e.Column.DisplayIndex = 6; 
        break; 
       } 
      case "estimatedED": 
       { 
        e.Column.DisplayIndex = 7; 
        break; 
       } 
      case "IMS_Hours": 
       { 
        e.Column.DisplayIndex = 8; 
        break; 
       } 
      case "ETC_Hours": 
       { 
        e.Column.DisplayIndex = 9; 
        break; 
       } 
     } 
    } 

這並不完全正常工作。對於此數據網格,順序應爲: taskName,overallPercentComplete,TDO_ID,WBS_ID,baseLineSD,baseLineED,estimatedSD,estimatedED,IMS_Hours,ETC_Hours。

我想通過修改Column.DisplayIndex屬性來正確設置它。 但是,當此代碼實際執行時,順序爲: taskNme,baseLineEd,TDO_ID,WBS_ID,overallPercentComplete,baseLineSD,estimatedED,estimatedSD,ETC_Hours,IMS_Hours。

任何想法?任何幫助將不勝感激。提前致謝。

*編輯*

void dataGrid1_Loaded(object sender, RoutedEventArgs e) 
    { 
     dataGrid1.Columns[0].DisplayIndex = 6; 
     dataGrid1.Columns[1].DisplayIndex = 7; 
     dataGrid1.Columns[2].DisplayIndex = 8; 
     dataGrid1.Columns[3].DisplayIndex = 9; 
     dataGrid1.Columns[4].DisplayIndex = 4; 
     dataGrid1.Columns[5].DisplayIndex = 5; 
     dataGrid1.Columns[6].DisplayIndex = 3; 
     dataGrid1.Columns[7].DisplayIndex = 2; 
     dataGrid1.Columns[8].DisplayIndex = 0; 
     dataGrid1.Columns[9].DisplayIndex = 1; 
    } 

還是什麼都沒有,但與加載的事件處理程序,我得到一個錯誤:

Index was out of range. Must be non-negative and less than the size of the collection. 
Parameter name: index 

Error Details: 
at System.ThrowHelper.ThrowArgumentOutOfRangeException() 
at System.Collections.Generic.List`1.get_Item(Int32 index) 
at System.Collections.ObjectModel.Collection`1.get_Item(Int32 index) 
at camDashboard.Views.Details.dataGrid1_Loaded(Object sender, RoutedEventArgs e) 
at MS.Internal.CoreInvokeHandler.InvokeEventHandler(UInt32 typeIndex, Delegate handlerDelegate, Object sender, Object args) 
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName, UInt32 flags) 
+0

我不知道,也許這是不可能的。我也嘗試了一個Loaded事件。依然沒有。發佈上面的代碼... – jwebster 2012-04-25 20:13:34

回答

3

不幸的是,這在今天的Silverlight中確實似乎是不可能的。

已經使用WPF中的AutoGeneratedColumns事件生成了一個工作解決方案,我已經用Reflector檢查了Silverlight DataGrid源代碼,並且首先沒有AutoGeneratedColumns事件,其次,它們確實對GenerateColumns()(無論您的顯示索引設置如何,都使用固定的算法調用您的事件處理程序的位置。

如果有任何興趣,我可以使用WPF解決方案更新此佔位符。

0

它看起來並不像它的真可能。看到這裏:http://forums.silverlight.net/t/144247.aspx

+0

我已經讀過那個非常相同的論壇。雖然,我很難相信這是不可能的。程序改變你的表的順序似乎有點荒謬,贊成按字母順序排列,並且不允許你重新排列它們並使它們處於某種正常的順序。 – jwebster 2012-04-25 19:55:34

+0

如果您事先知道所有列,爲什麼不直接設置它們而不使用AutoGenerateColumns? – RobSiklos 2012-04-26 17:51:13

+0

看起來我必須這樣做。這意味着創建一些解決方法,但看起來我不會有太多選擇。多謝你們。 – jwebster 2012-04-26 23:18:59

0

嗯,我得到了這個工作。幾乎所有我能想出來的唯一方法就是不使用AutoGenerating Columns,只是自己在XAML中定義列。這是我如何做的,如果任何人有興趣。

<sdk:DataGrid AutoGenerateColumns="False" Height="392" Margin="32,360,36,0" Name="dataGrid3" VerticalAlignment="Top" ItemsSource="{Binding}" IsReadOnly="True" > 
     <sdk:DataGrid.Columns> 
      <sdk:DataGridTextColumn x:Name="TDO1" Binding="{Binding Path=TDO_ID, Mode=OneWay}" Header="TDO_ID" IsReadOnly="True" Width="100" /> 
      <sdk:DataGridTextColumn x:Name="taskName1" Binding="{Binding Path=taskName, Mode=OneWay}" Header="taskName" IsReadOnly="True" Width="304" /> 
      <sdk:DataGridTextColumn x:Name="weekName" Binding="{Binding Path=weekName, Mode=OneWay}" Header="weekName" IsReadOnly="True" Width="200" /> 
      <sdk:DataGridTextColumn x:Name="scheduleVariance" Binding="{Binding Path=scheduleVariance, Mode=OneWay}" Header="SV (Days)" IsReadOnly="True" Width="100" /> 
      <sdk:DataGridTextColumn x:Name="schedulePerformanceIndex" Binding="{Binding Path=schedulePerformanceIndex, Mode=OneWay}" Header="SPI" IsReadOnly="True" Width="100" /> 
      <sdk:DataGridTextColumn x:Name="ECD" Binding="{Binding Path=ECD, Mode=OneWay}" Header="ECD" IsReadOnly="True" Width="100" /> 
      <sdk:DataGridTextColumn x:Name="percentComplete" Binding="{Binding Path=percentComplete, Mode=OneWay}" Header="% Complete" IsReadOnly="True" Width="100" /> 
      <sdk:DataGridTextColumn x:Name="percentExpected" Binding="{Binding Path=percentExpected, Mode=OneWay}" Header="% Expected" IsReadOnly="True" Width="100" /> 
      <sdk:DataGridTextColumn x:Name="WBS1" Binding="{Binding Path=WBS_ID, Mode=OneWay}" Header="WBS_ID" IsReadOnly="True" Width="100" /> 
     </sdk:DataGrid.Columns> 
    </sdk:DataGrid> 

我很抱歉,它的所有混亂。不太清楚如何解決這個問題,因爲線條太長了。小心所有。

-1
void autogen() 
{ 
    cmd = new SqlCommand("select count(*) from Employee", con); 
    dr = cmd.ExecuteReader(); 
    while (dr.Read()) 
    { 
     i = int.Parse(dr[0].ToString()) + 1; 

    } 
    dr.Close(); 
    cmd.Dispose(); 
    if (i <= 9) 
    { 
     TextBox1.Text = "EID0" + i.ToString(); 
    } 
    else if (i <= 99) 
    { 
     TextBox1.Text = "EID" + i.ToString(); 
    } 

} 
1

的方式,即我理解,當AutoGenerateColumns被設定爲True WPF將數據呈現網格列是:如果正在針對ClassA的從ClassB的繼承產生的結構,產生的次序是ClassA和然後ClassB的用包含數據的ClassA和ClassB中屬性的聲明順序。

,我已經設計我的課的方式是,屬性會在功能意義順序定義,我會控制與自定義屬性SortIndexAttribute與指數的任何整數值的屬性定義爲[SortIndex(1)]的順序。

所以,我也是,面對很多克服這個挑戰。

我的思維方式是,與定義的排序指標,我可以相應地重新安排我的屬性,然後在AutoGeneratingColumn事件DataGridColumn的設置DisplayIndex在運行時。

但是,我面臨着一個新的挑戰。如果屬性的聲明順序和排序索引不匹配,並且在設置時,如果排序索引大於列計數,則會引發錯誤。 DisplayIndex設置時,可以爲0或小於列數(注意:一次生成並填充一列;同樣,當未設置DisplayIndex時,它存儲不能手動分配的-1)

I我還沒有實現下面的邏輯,但它可能只是工作。 1.創建ClassA的所有屬性(本地和繼承)的排序列表 2.在DataGridColumnAutoGeneratingColumn事件中,將第一列的DisplayIndex設置爲0 3.現在,按照我映射,我將分配0或1爲新列wrt到第一個等等.. 4.如果排序索引不可用,我將它設置爲列計數或完全跳過並讓WPF處理它 - 尚未

IMPLEMENTED爲了解釋#3清楚,生成特性的順序和排序索引是如下: 僱員:名稱(1),ID(0),地址(99),ZIPCODE(50)

WPF將按照以上順序生成列。所以在AutoGeneratingColumn事件,我將執行如下對我的屬性:

  1. 名稱(1):設置DisplayIndex = 0(將插入在首位)
  2. ID(0):設置DisplayIndex = 0(應置換存在於0)
  3. 地址(99):設置DisplayIndex = 2(標記與列數或簡單地跳過)
  4. ZIPCODE(50):設置DisplayIndex = 2(應置換爲0的現有的)

下面是我的最終代碼:

private int SetDisplayIndex(string propName) 
    { 
    int result = -1; 
    int curr = dictPropertySortIndexMap.GetValueFromKey[propName]; 
    int last = dictPropertySortIndexMap[nameSortLast]; 

    // For the first property in order, always set 0 
    if (nameSortLast.IsBlank()) 
     result = 0; 

    // For the property with lower index than sorted at first position 
    else if (curr > dictColumnsSorted.Values.Max()) 
     result = dgrdUniversal.Columns.Count; 

    // For the property with higher index than sorted at last position 
    else if (curr < dictColumnsSorted.Values.Min()) 
     result = 0; 

    else // For the property to be inserted between 
     result = dictColumnsSorted[dictPropertySortIndexMap[ 
      dictPropertySortIndexMap._Where(
      p => dictColumnsSorted.Keys.Contains(p.Key) && p.Value > curr)     ._Select(p => p.Value)._Min()]]; 

    dictColumnsSorted.Add(propName, result); 
    nameSortLast = propName; 

    return result; 
    } 




請嘗試這一點,並留下您的意見。

感謝, Rupak