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、estimatedSD、estimatedED、IMS_Hours、ETC_Hours。

Column.DisplayIndex プロパティを変更して、正しく設定することを考えました。ただし、このコードが実際に実行されると、順序は次のとおりです。

何か案は?どんな助けでも大歓迎です。前もって感謝します。

*編集*

  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

私が理解した方法は、WPFAutoGenerateColumnsが設定されてTrueいる場合にデータ グリッド列をレンダリングする方法です。構造体が ClassB から継承する ClassA に対して生成されている場合、生成の順序は ClassA であり、次に ClassB のプロパティの宣言の順序です。データを含む ClassA および ClassB。

私がクラスを設計した方法は、プロパティが機能的に重要な順序で定義され、任意の整数値としてのインデックスと同様SortIndexAttributeに、プロパティで定義されたカスタム属性で順序を制御するというものでした。[SortIndex(1)]

ですから、私もこれを克服するために多くの挑戦に直面しました。

私が考えた方法は、定義されたソート インデックスを使用して、それに応じてプロパティを再配置し、DisplayIndex実行時AutoGeneratingColumnDataGridColumn.

しかし、私は新たな課題に直面しています。プロパティと と のソート インデックスの宣言の順序が一致しない場合、 and の設定中に、ソート インデックスが列数よりも大きい場合、エラーがスローされます。DisplayIndex、設定中は、0 または列数未満にすることができます (注: 列は一度に 1 つずつ生成されて入力されます。また、DisplayIndexが設定されていない場合は、手動で割り当てることができない -1 が格納されます)

以下のロジックはまだ実装していませんが、うまくいくかもしれません。1. ClassA のすべてのプロパティ (ネイティブと継承の両方) のソート済みリストを作成します 2. のAutoGeneratingColumn場合、最初の列の を 0DataGridColumnに設定DisplayIndexします 3. ここで、マッピングの順序に従って、0 を割り当てますまたは最初の列の新しい列の場合は1など.. 4.ソートインデックスが利用できない場合は、列数に設定するか、完全にスキップしてWPFに処理させます-まだ実装されていません

#3 をわかりやすく説明すると、プロパティとソート インデックスの生成順序は次のとおりです。 従業員: 名前(1)、ID(0)、住所(99)、郵便番号(50)

WPF は、上記の順序で列を生成します。したがって、AutoGeneratingColumnイベントでは、プロパティに対して以下のように実装します。

  1. 名前(1): セットDisplayIndex = 0(最初に挿入します)
  2. ID(0): 設定DisplayIndex = 0(既存のものを 0 に置き換える必要があります)
  3. Address(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 に答える