Silverlight 3- Listbox : 부드러운 스크롤을 달성하고 Mousedown/Mouseup 이벤트를 잡는 방법

StackOverflow https://stackoverflow.com/questions/1354708

문제

나는 내 필요에 대해 Listbox의 동작을 조정하려고 노력하고 있으며 몇 가지 문제를 해결했습니다.

1) ListBox의 스크롤 위치를 프로그래밍 방식으로 설정할 수있는 방법
ListBox는 내부 스크롤 리어에 대한 액세서를 제공하지 않으므로 원하는 곳으로 스크롤 할 수 없습니다.

2) 세로 스크롤을 정확하게 설정하는 방법 (즉, 매끄러운 스크롤을 갖는 방법)?
기본적으로 한 번에 하나의 완전한 요소를 스크롤하여 목록을 스크롤하는 방법이 없습니다 (Listbox는 항상 첫 번째 요소가 완전히 표시되는지 확인합니다).

이 동작은 대부분의 경우 괜찮지 만 내 것이 아닙니다 : 나는 부드러운 움직임을 원합니다 ...),

WPF 의이 문제에 대한 해결책이 있지만 Silverlight는 아닙니다 (질문 참조 "IS-IT-IT-IT-IMPLEMENT-SMOOD-SCROLL-in-WPF-LISTVIEW" ).

3) Mousedown 및 Mouseup 이벤트를 잡는 방법 :
ListBox를 서브 클래스하면 Mouseup 및 MouseMove 이벤트를 잡을 수 있습니다. 그러나 마우스 업 이벤트는 해고되지 않습니다 (Listbox 하위 요소에 의해 먹는 것으로 생각됩니다).

도움이 되었습니까?

해결책

나는 대답을 찾았으므로 나 자신에게 대답 할 것입니다.


1) ListBox를 부드럽게 스크롤하게 만드는 방법 :
이 문제는 Silverlight 2에서 발생하지 않았으며 가상화 된 스태크 패널이 도입 된 Silverlight 3에서만 발생했습니다.
VirtualizedStackPanel은 거대한 목록의 경우 훨씬 더 빠른 새로 고침을 가능하게합니다 (가시 요소 만 그려지기 때문에)

이에 대한 해결 방법이 있습니다 (대규모 목록에서 사용해서는 안됩니다) : StackPanel을 사용하도록 ListBox의 ItemPanelTemplate를 재정의합니다.

<navigation:Page.Resources>
    <ItemsPanelTemplate x:Key="ItemsPanelTemplate">
        <StackPanel/>
    </ItemsPanelTemplate>
</navigation:Page.Resources>

<StackPanel Orientation="Vertical"  x:Name="LayoutRoot">                       
        <ListBox x:Name="list" ItemsPanel="{StaticResource ItemsPanelTemplate}">
        </ListBox>
</StackPanel>

2) 스크롤 위치를 프로그래밍 방식으로 변경하는 방법
아래 ListBox의 하위 클래스 참조 : ListBox의 내부 스크롤 뷰어에 대한 액세서를 제공합니다.


3) ListBox에서 Mousedown / Move / UP 이벤트를 잡는 방법 :

아래와 같이 ListBox의 서브 클래스를 만듭니다. 3 가지 방법 :

 internal void MyOnMouseLeftButtonDown(MouseButtonEventArgs e)  
 protected override void OnMouseMove(MouseEventArgs e)  
 protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)  

부름을 받고 원하는대로 할 수 있습니다. OnMouseleftButtondown의 ListBox 방법을 호출하지 않는 미묘한 트릭이 있습니다.이 이벤트를 처리 할 수있는 ListBoxItem의 서브 클래스를 구현해야합니다.

using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MyControls
{
  //In order for this class to be usable as a control, you need to create a folder
  //named "generic" in your project, and a "generic.xaml" file in this folder
  //(this is where you can edit the default look of your controls)
  //
  /*
   * Typical content of an "empty" generic.xaml file : 
    <ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:VideoControls">
    </ResourceDictionary>
   */
  public class MyListBox : ListBox
  {
    public MyListBox()
    {
        DefaultStyleKey = typeof(ListBox);
    }

    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();
    }

    #region ScrollViewer / unlocking access related code
    private ScrollViewer _scrollHost;
    public ScrollViewer ScrollViewer
    {
      get 
      {
        if (_scrollHost == null)
          _scrollHost = FindVisualChildOfType<ScrollViewer>(this);
        return _scrollHost; 
      }
    }

    public static childItemType FindVisualChildOfType<childItemType>(DependencyObject obj)
      where childItemType : DependencyObject
    {
      // Search immediate children first (breadth-first)
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
      {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);

        if (child != null && child is childItemType)
          return (childItemType)child;

        else
        {
          childItemType childOfChild = FindVisualChildOfType<childItemType>(child);

          if (childOfChild != null)
            return childOfChild;
        }
      }

      return null;
    }
    #endregion

    //Modify MyListBox so that it uses MyListBoxItem instead of ListBoxItem
    protected override DependencyObject GetContainerForItemOverride()
    {
      MyListBoxItem item = new MyListBoxItem(this);
      if (base.ItemContainerStyle != null)
      {
        item.Style = base.ItemContainerStyle;
      }

      return item;
    }

    //OnMouseLeftButtonUp is never reached, since it is eaten by the Items in the list...
    /*
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
      base.OnMouseLeftButtonDown(e);
      e.Handled = false;
    }
    */

    internal void MyOnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
      base.OnMouseMove(e);
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
      base.OnMouseLeftButtonUp(e);
    }


  }






  public class MyListBoxItem : ListBoxItem
  {
    MyListBox _customListBoxContainer;

    public MyListBoxItem()
    { }

    public MyListBoxItem(MyListBox customListBox)
    {
      this._customListBoxContainer = customListBox;
    }

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
      base.OnMouseLeftButtonDown(e);

      if (this._customListBoxContainer != null)
      {
        this._customListBoxContainer.MyOnMouseLeftButtonDown(e);
      }

    }
  }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top