0

Visual Studio 2008、.Net3.5を使用する

たくさんのアイテムがロードされたListViewがあります。アイテムを削除するための右クリックポップアップがあります。アイテムを削除した後、プライマリデータに再度アクセスしてリストビューを再描画し、選択したアイテムをリセットします。ただし、選択したアイテムは選択済みとして表示されません。

コードのアイデア:

public ListView m_lv;  
public MyDataCollection m_Data;  // Has a function to get data based on a tag.  

public void RemoveEventHandler(object sender, EventArgs e)  
{  
  int iSelectedItem= m_lv.FocusedItem.Index;

  int iDataIndexToRemove= m_Data.GetIndexOf(m_lv.FocusedItem.Tag.ToString());  

  m_Data.RemoveAt(iDataIndexToRemove);  // Remove the item.  

  if(0 != m_lv.Items.Count)  
  {  
    if(iSelectedItem == m_Data.Items.Count)  // Removed last.  
      iSelectedItem= m_Data.Items.Count - 1;  
  }

  m_lv.Items.Clear();  // Clear the list view items.  

  // Completely rebuild the list view.  
  foreach(MyData md in m_Data)  
  {  
    ListViewItem lvi= new ListViewItem(md.Column0.ToString());  
    lvi.SubItems.Add(md.Column1.ToString());  
    lvi.SubItems.Add(md.Column3.ToString());  
    lvi.SubItems.Add(md.Column4.ToString());  

    m_lv.Items.Add(lvi);  
  }  

  // Set up tags, column sizes, etc.  

  if(0 != m_lv.Items.Count)  
    m_lv.Items[iSelectedItem].Selected= true;  // Set the selection.      
}  

上記のようなことをすると、列のサイズを変更したり並べ替えたりしない限り、選択したアイテムが選択したものとして視覚的に表示されることはありません(背景色の変更はありません)。次に、選択済みとして表示されます。ただし、デバッガーを使用するか、ボタンを追加してメッセージボックスを使用して選択したアイテムを表示すると、アイテムは選択されていることを認識します。

私はそれが何らかのリフレッシュ/描画の問題であることを知っています-何かアイデアはありますか?

4

4 に答える 4

2

右クリックポップアップの結果、ListViewにフォーカスがなく、にHideSelection設定されているようtrueです。これは、アイテム選択されている間、WinFormsがそのアイテムを表示していないことを意味します。最初にオフHideSelectionにしてチェックしてから、フォーカスをリストビューに戻すためのコードが必要になります。

加えて:

  1. を使用するListView.Items.Clear()と、列が失われることはないため、毎回列を再追加する必要があります(これにより、列ヘッダーのサイズを変更したユーザーを苛立たせることになります)。
  2. 明確でリフレッシュすること全体を行わないでください。それぞれListViewItemNameプロパティを主キーとして設定すると、次のことができます。ListViewItem liToRemove = listView[name];
于 2010-02-17T22:53:10.113 に答える
0

選択を設定した後、ListViewでInvalidateメソッドを呼び出してみてください。

于 2010-02-17T22:56:13.057 に答える
0

これを使って:

m_lv.BeginUpdate();

//アイテムを追加します

m_lv.EndUpdate();
//
if(0!= m_lv.Items.Count)  
    m_lv.Items [iSelectedItem] .Selected = true; //選択を設定します。   

'Invalidate'を呼び出さないでください。Begin/EndUpdateを使用すると、ちらつきや更新を防ぐことができます。

編集:ステートメントの背後にある私の理由を説明するために... BeginUpdateはすべてのWM_PAINTメッセージをフリーズします... EndUpdateはWM_PAINTのフリーズを解除します。これにより、リストへのアイテムの追加がはるかに速く表示され、とにかく、EndUpdateの呼び出し後に更新されます!どちらの方法でも選択できます。EndUpdateの外に配置することをお勧めします...それが私の意見です...InvalidateはWM_PAINTメッセージを生成しますが、必ずしもすぐに処理されるとは限りません...でInvalidate()を呼び出すことはお勧めできません更新が遅くなるため、アイテムが追加されるループ!

これがお役に立てば幸いです、よろしく、トム。

于 2010-02-17T23:11:56.153 に答える
0

それはかなり簡単になりました:

// Figure out index of item to remove, iRemoved, do some work....  

m_lv.Items.RemoveAt(iRemoved);  
m_lv.Refresh();

// Figure out what is left so new selection, iNewSelection, can be set....
m_lv.Items[iNewSelection].Selected = true;  

この投稿を更新していなかったことを忘れました!

于 2011-10-05T18:54:44.740 に答える