1

我正在使用 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、estimateSD、estimateED、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;
    }

仍然没有,但是使用 Loaded 事件处理程序,我得到一个错误:

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)
4

5 回答 5

3

不幸的是,这在今天的 Silverlight 中似乎确实是不可能的。

在 WPF 中使用 AutoGeneratedColumns 事件生成了一个可行的解决方案后,我使用 Reflector 检查了 Silverlight DataGrid 源代码,首先,没有 AutoGeneratedColumns 事件,其次,它们确实对内部的列进行了排序GenerateColumns()(您的事件处理程序的位置是无论您的显示索引设置如何,都使用固定算法调用。

如果有任何兴趣,我可以使用 WPF 解决方案更新这个占位符。

于 2012-04-25T20:26:10.010 回答
1

我理解的方式,当AutoGenerateColumns设置为WPF 呈现数据网格列时True:如果结构是针对继承自 ClassB 的 ClassA 生成的,则生成顺序是 ClassA,然后是 ClassB,其属性的声明顺序是包含数据的 ClassA 和 ClassB。

我设计类的方式是按功能重要性的顺序定义属性,并且我将使用在属性上定义的自定义属性来控制顺序,SortIndexAttribute就像[SortIndex(1)]将索引作为任何整数值一样。

所以,我也面临着克服这一点的很多挑战。

我的想法是,使用定义的排序索引,我可以相应地重新排列我的属性,然后DisplayIndex在运行时AutoGeneratingColumn设置DataGridColumn.

然而,我面临着新的挑战。如果属性的声明顺序和排序索引不匹配,并且在设置时,如果排序索引大于列数,则会引发错误。DisplayIndex, 设置时,可以为 0 或小于列数(注意:列一次生成并填充一个;另外,DisplayIndex未设置时,它存储 -1,无法手动分配)

我还没有实现以下逻辑,但它可能会起作用。1. 创建 ClassA 的所有属性(包括原生属性和继承属性)的排序列表 2. 在 的AutoGeneratingColumn情况下DataGridColumnDisplayIndex将第一列的设置为 0 3. 现在,根据我的映射中的顺序,我将分配 0或 1 表示新列 wrt 到第一个,依此类推。 4. 如果排序索引不可用,我将其设置为列数或完全跳过并让 WPF 处理它 - 尚未实现

为了清楚地解释#3,属性和排序索引的生成顺序如下: Employee: Name(1), ID(0), Address(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;
  }




请试试这个并留下您的意见。

谢谢, 鲁帕克

于 2014-05-11T18:51:14.740 回答
0

看起来不太可能。见这里:http ://forums.silverlight.net/t/144247.aspx

于 2012-04-25T19:36:34.470 回答
0

好吧,我得到了这个工作。几乎我能弄清楚这一点的唯一方法是不使用自动生成列,而只是自己在 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>

我很抱歉这一切都混乱了。不太确定如何解决这个问题,因为线路太长了。照顾好一切。

于 2012-04-27T13:27:33.813 回答
-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();
    }

}
于 2012-05-26T11:18:02.757 回答