0

クラスと、このクラスを使用してリスト内のリストを提供する一連の IEnumerables があります。(詳細については、この質問の回答を参照してください。)

コードは次のとおりです。

public IEnumerable<IEnumerable<WorkItemColumn>> EnumerateResultSet(WorkItemCollection queryResults)//DisplayFieldList displayFieldList)
{
    foreach (WorkItem workItem in queryResults)
    {
        yield return EnumerateColumns(queryResults.DisplayFields, workItem);   
    }
}

public IEnumerable<WorkItemColumn> EnumerateColumns(DisplayFieldList resultSet, WorkItem workItem)
{
    foreach (FieldDefinition column in resultSet)
        yield return new WorkItemColumn { Name = column.Name, Value = workItem[column.Name], WorkItemForColumn = workItem};
}

そしてクラス:

public class WorkItemColumn
{
    public string Name { get; set; }
    public object Value { get; set; }
    public WorkItem WorkItemForColumn { get; set; }
}

この結果を ListBox の ItemsSource に設定しました

Form.QueryResultListSource = EnumerateResultSet(queryResults);

このリスト ボックスのイベントをキャッチしようとすると、問題が発生します。

public void QueryResultsSelectionChanged(SelectionChangedEventArgs e)
{
                                                   +-----------------+
                                                   v                 | 
    foreach (WorkItemColumn workItemColumn in e.AddedItems)          |
    {                                                                |
        AddWorkItemToPad(workItemColumn.WorkItemForColumn);          |
    }                                                +---------------|
                                                     |               |
                                                     v               |    
    foreach (WorkItemColumn workItemColumn in e.RemovedItems)        |
    {                                                                |
        RemoveWorkItemFromPad(workItemColumn.WorkItemForColumn);     |
    }                                                                |
                                                                     |    
}                                                                    |
                                                                     |
These items are where the problem is --------------------------------+

デバッグ中に e.AddedItems[0] を調べると、そのタイプは EnumerateColumns であると表示されます。

その型にキャストしようとすると、Visual Studio は (当然のことながら) EnumerateColumns はメソッドですが、型のように使用されると言っています。

では、これをタイプ別に参照して、foreach ループを実行し、その中のものを取得するにはどうすればよいでしょうか?


これは、答えに基づいて更新されたコードです。

public void QueryResultsSelectionChanged(SelectionChangedEventArgs e)
{
    foreach (IEnumerable<WorkItemColumn> workItemColumns in e.AddedItems)
    {
        if (workItemColumns.Count() > 0)
            AddWorkItemToPad(workItemColumns.First().WorkItemForColumn);                
    }

    foreach (IEnumerable<WorkItemColumn> workItemColumns in e.RemovedItems)
    {
        if (workItemColumns.Count() > 0)
            RemoveWorkItemFromPad(workItemColumns.First().WorkItemForColumn);    
    }
}
4

4 に答える 4

2

問題は、最初の方法では、最初の方法で得られた各結果が得られないことです。つまり、列挙可能なもの自体が得られます。イテレータ用にコンパイラが生成した型ですが、重要なのは、を実装すること IEnumerable<WorkItemColumn>です。

必要に応じて各アイテムをキャストできますIEnumerable<WorkItemColumn>が、で何をしようとしているのかは明確ではありませんQueryResultsSelectionChanged。あなたがしたいかもしれません:

foreach (IEnumerable<WorkItemColumn> workItemColumns in e.AddedItems)
{                                                   
    foreach(WorkItemColumn workItemColumn in workItemColumns)
    {
        AddWorkItemToPad(workItemColumn.WorkItemForColumn); 
    }
}

など...またはあなたはしないかもしれません。あなたが本当に何をしようとしているのかを知らずに言うのは難しいです。とにかく、それの核心は、あなたが現在、一連のアイテムを単一のアイテムとして扱わせようとしているということです。それをしないでください:)

于 2009-12-28T23:41:05.597 に答える
1

e.AddedItems[0]コンパイラによって生成された非表示のイテレータ型のインスタンスであり、直接使用することはできません。
ただし、を実装IEnumerable<WorkItemColumn>しているため、そのインターフェイスから使用できます。

言い換えると:

foreach (IEnumerable<WorkItemColumn> colSet in e.RemovedItems)        
    foreah(WorkItemColumn workItemColumn in colSet)
        RemoveWorkItemFromPad(workItemColumn.WorkItemForColumn);     
于 2009-12-28T23:41:32.613 に答える
1

イテレータを使用することはおそらくこの問題に対する最良のアプローチではありませんが、次のように列挙を配列に格納することで、発生している問題を回避できる可能性があります。

using System.Linq;
...
Form.QueryResultListSource = EnumerateResultSet(queryResults).ToArray();

EnumerateResultSet を次のように変更します。

public IEnumerable<WorkItemColumn[]> EnumerateResultSet(WorkItemCollection queryResults)//DisplayFieldList displayFieldList) 
{ 
    foreach (WorkItem workItem in queryResults) 
    { 
        yield return EnumerateColumns(queryResults.DisplayFields, workItem).ToArray();    
    } 
} 

他の人が指摘したように、yield キーワードを使用すると、列挙したいアイテムを反復処理する方法を知っている関数を効果的に返しています。ただし、データ ソースをこの列挙型に設定しても、一度実行して結果を保存するだけではありません。結果を使用する必要があるときはいつでも、反復を最初からやり直す必要があるため、反復子を使用すると多くのパフォーマンスの問題が発生する可能性があります。

于 2009-12-28T23:50:46.230 に答える
0

AddedItems完全を期すために、 およびに関連するコードを含める必要がありRemovedItemsます。

それにもかかわらず、型名を完全修飾形式 (名前空間が含まれていることを意味します) でオブジェクトをキャストします。メソッドは型レベルでは使用できませんが、サブタイプは使用できるため、これにより、メソッド シグネチャではなく型にバインドされます。

于 2009-12-28T23:45:50.907 に答える