2011-09-30 33 views
5

Görünüm kümesi görünümünde bir ListView olan bir .NET 3.5 WinForm sahibim. Uzun bir arka plan görevinde kaydırılabilir bir durum öğeleri listesi olarak çalışır. En son eklenen ListViewItem (durum girişi) aşağıya eklendim. Görüldüğünden emin olmak için, ekledikten sonra yeni öğenin görünürlüğünü sağlarım. Her şey yolunda; Liste görünümü otomatik olarak en son öğeyi göstermek için aşağı doğru kaydırır.ListView kaydırma kontrolü - kullanıcı kaydırmıyorsa aşağıya kaydırın?

private void AddListItem(DateTime timestamp, string message, int index) 
{ 
    var listItem = new ListViewItem(timestamp.ToString()); 
    listItem.SubItems.Add(message); 
    statusList.Items.Insert(index, listItem); 
    statusList.Items[statusList.Items.Count - 1].EnsureVisible(); 
} 

, ListView o geliyor gibi yeni öğe görünür hale getirmek için aşağı kaydırıldığında edilecek kullanıcı eski iletiyi bakmak için yukarı kaydırma olup olmadığını sorun olduğunu. Denetlemek için bu davranışını denetlemek için bir yolu var mı Kullanıcı, kaydırma çubuğuyla (özellikle, kaydırma çubuğundaki fare düğmesini basılı tutuyorlarsa) etkileşiyor? Kaydırma her zaman altta ise, algılanması da muhtemelen kabul edilebilir. En altta değilse, en son öğenin görünürlüğünü garanti etmem. Bir şey gibi:

private void AddListItem(DateTime timestamp, string message, int index) 
{ 
    var listItem = new ListViewItem(timestamp.ToString()); 
    listItem.SubItems.Add(message); 
    statusList.Items.Insert(index, listItem); 
    if (!statusList.IsScrollbarUserControlled) 
    { 
     statusList.Items[statusList.Items.Count - 1].EnsureVisible(); 
    } 
} 

Garip olan kullanıcı yerine kaydırma "kolu" basılı tutarak zaman, sap (görünüm aslında programlama yoluyla aşağı kaydırılan varlık değildir ima) taşımak, ancak içinde olmamasıdır infact.

Güncelleştirme: Kaydırma çubuğunun konumunu algılamak mümkün mü, altta değil mi?

cevap

2

SysInternals 'ProcMon ile karşılaştırın. Kullanıcıyı kapatabilmek için "Otomatik kaydırma" etiketli bir onay kutusu ekleyin. Bu sorunu çözmek için

+0

Bunun neden -1'den olduğuna emin değilim. Bu soruya cevap vermezken, çok makul bir alternatif sağladınız. –

+0

@Stealth - bazı at ayakkabıları sistematik olarak yanıtlarımı düşürüyor. Hiçbir fikrim yok, bunun için endişelenme. Oy verdiğin için teşekkürler. –

+0

Buradaki her iki cevap da doğru görünüyor, ama sonuç olarak öneriye katılıyorum çünkü kullanıcı ihtiyaçlarını daha fazla karşıladığını düşünüyorum ve bunun nasıl işleyeceğine daha az şaşırır. İşlemci İzleyicisi'ni önerdiğiniz gibi kullandım ve bir UX deneyimi için iyi çalışıyor. –

4

İki adım:

  1. WinForms ListView bir kaydırılan olayı yoktur. Bir tanımlamamız gerekecek.
  2. ListView öğesinin ne zaman boşta kaldığını belirleme ve yalnızca bir süre boşta kaldığında EnsureVisible öğesini çağırmak. İlk sorun için

, ListView yeni bir sınıf miras, Windows mesajı pompasını geçersiz ve kaydırdığı o zaman bir olay yükseltmek:

public class MyListView : ListView 
{ 
    public event EventHandler<EventArgs> Scrolled; 

    protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 

     const int wm_vscroll = 0x115; 
     if (m.Msg == wm_vscroll && Scrolled != null) 
     { 
      Scrolled(this, new EventArgs()); 
     } 
    } 
} 

Şimdi liste Kullanıcı görünümü kaydırdığında biliyorum görünüm. Bir sonraki problem, liste görünümünün boşta olup olmadığını belirlemek; Diğer bir deyişle, kullanıcı bir süredir kaydırma yapmamışsa.

Bunu yapmanın çeşitli yolları vardır. Bu amaçla, sadece son kaydırma süresini belirtmek için bir zaman damgası kullanacağım:

+0

Bu performansın ne kadarı var? Bu geçmişte kullandığınız bir şey mi? –

+0

Performans isabet görmezsiniz. –

+0

Bu 0x115 sabitinin nereden geldiğini merak ediyorum. –

İlgili konular