سيلفرلايت 3 - مربع القائمة: كيفية تحقيق السلس التمرير والصيد الأحداث MouseDown / MouseUp

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

سؤال

وأنا أحاول أن التكيف مع سلوك مربع القائمة لتلبية احتياجات بلدي وأنا واجهت العديد من المشاكل

1) كيف يمكنك برمجيا تعيين موضع التمرير من مربع القائمة على
مربع القائمة لا يوفر استرجاع لScrollViewer لها الداخلي بحيث لا يمكن التمرير إلى أي مكان تريد.

2) كيفية تعيين بدقة التمرير الرأسي (أي كيف يكون التمرير السلس) منتديات افتراضيا، لا توجد وسيلة لتمرير القائمة الأخرى عن طريق التمرير عنصر كاملة في وقت واحد (مربع قائمة سوف دائما التأكد من أن يظهر العنصر الأول تماما)

وهذا السلوك على ما يرام في معظم الحالات، ولكن ليس لي: أريد الحركة السلسة ...)،

وهناك حل لهذه المشكلة مع برنامج الأغذية العالمي، ولكن ليس مع Silverlight (انظر السؤال <في أ href = "https://stackoverflow.com/questions/1033841/is-it-possible-to-implement-smooth-scroll -في واحد في برنامج الأغذية العالمي، listview ">" هو-هو-ممكن-لتطبيق برنامج ضمان سلاسة التمرير-في-برنامج الأغذية العالمي، listview ").

و3) كيفية التقاط الأحداث MouseDown وMouseUp:
إذا كنت فرعية مربع القائمة، قد تكون قادرة على التقاط الأحداث MouseUp وMouseMove. ومع ذلك الحدث MouseUp يتم تشغيل أبدا (وأظن يتم تناولها من قبل العناصر الفرعية مربع القائمة)

هل كانت مفيدة؟

المحلول

ولقد وجدت الجواب، ولذا فإنني سوف أجيب على نفسي.


1) كيفية جعل التمرير مربع القائمة بسلاسة:
لم يحدث هذه المشكلة في سيلفرلايت 2، ويحدث ذلك فقط مع سيلفرلايت 3، حيث تم طرح VirtualizedStackPanel.
وVirtualizedStackPanel تمكن أسرع بكثير تجديد في حالة قوائم ضخمة (كما يتم رسمها فقط عناصر مرئية)

وهناك حلا لهذه (حذار، فإنه لا ينبغي أن تستخدم على قوائم ضخمة): كنت إعادة ItemPanelTemplate مربع القائمة، حتى أنه يستخدم StackPanel:

<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) كيفية تغيير برمجيا موقف التمرير و
اطلع على فئة فرعية من مربع القائمة أدناه: أنه يوفر استرجاع إلى ScrollViewer الداخلي للمربع القائمة


و3) كيف للقبض على MouseDown / نقل / الأحداث حتى في مربع القائمة:

وإنشاء فئة فرعية من مربع القائمة كما هو موضح أدناه. أساليب 3:

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

وسوف يطلق ويمكنك أن تفعل ما تريد معهم. هناك واحد خدعة خفية وهو أن طريقة OnMouseLeftButtonDown من مربع القائمة أبدا يسمى: تحتاج إلى تنفيذ فئة فرعية من 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