Windows Phone 8:从后面的代码中将 FrameworkElement 添加到 PanoramaItem [英] Windows Phone 8: Add FrameworkElement to PanoramaItem from code behind

查看:18
本文介绍了Windows Phone 8:从后面的代码中将 FrameworkElement 添加到 PanoramaItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从全景图后面的代码中将 FrameworkElements 添加到全景图时,会选择"全景图,导致非常糟糕的用户体验.

When I add FrameworkElements to a PanoramaItem from code behind the panorama "selects" the panoramaItem, causing a really bad user experience.

我做了一个小测试项目,重现了问题.

I made a small test project where the problem is reproduced.

Tha MainPage 仅包含包含三个项目的全景图:

Tha MainPage contains just a panorama with three items:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <phone:Panorama Name="m_Panorama">
        <phone:PanoramaItem Header="Item 1" 
                            Name="m_Item1">
            <StackPanel Orientation="Vertical" Name="m_Stack1">
            </StackPanel>
        </phone:PanoramaItem>
        <phone:PanoramaItem Header="Item 2" 
                            Name="m_Item2">
            <StackPanel Orientation="Vertical" Name="m_Stack2">
            </StackPanel>
        </phone:PanoramaItem>
        <phone:PanoramaItem Header="Item 3" 
                            Name="m_Item3">
            <StackPanel Orientation="Vertical" Name="m_Stack3">
            </StackPanel>
        </phone:PanoramaItem>            
    </phone:Panorama>
</Grid>

背后的代码使用 DispatcherTimer 开始向 PanoramaItems 添加元素:

The code behind uses a DispatcherTimer to start adding the elements to the PanoramaItems:

public partial class MainPage : PhoneApplicationPage
{
  public MainPage()
  {
    InitializeComponent();
  }

  protected override void OnNavigatedTo(NavigationEventArgs e)
  {
    base.OnNavigatedTo(e);
    if (e.NavigationMode == NavigationMode.New){
      StartDelayed(UpdateItem1, 1000);
      StartDelayed(UpdateItem2, 1000);
      StartDelayed(UpdateItem3, 1000);
    }
  }

  private void AddTextblock(StackPanel stackPanel, string text, bool animate)
  {
    TextBlock tb = new TextBlock();
    tb.Text = text;
    stackPanel.Children.Add(tb);

    if (animate){
      tb.Measure(new Size(double.MaxValue, double.MaxValue));
      tb.UpdateLayout();

      Storyboard sb = new Storyboard();
      DoubleAnimation anim = new DoubleAnimation();
      anim.Duration = new Duration(TimeSpan.FromMilliseconds(500));
      anim.From = 0;
      anim.To = tb.DesiredSize.Width;
      sb.Children.Add(anim);
      Storyboard.SetTarget(anim, tb);
      Storyboard.SetTargetProperty(anim, new PropertyPath("Width"));
      sb.Begin();
    }
  }

  private async void UpdateItem1(object sender, EventArgs e)
  {
    while (true){
      m_Stack1.Children.Clear();
      for (int i=0; i<10; i++){
        await Task.Delay(500);
        AddTextblock(m_Stack1, "This is item 1", false);
      }
    }
  }

  private async void UpdateItem2(object sender, EventArgs e)
  {
    while (true){
      m_Stack2.Children.Clear();
      for (int i=0; i<10; i++){
        await Task.Delay(1000);
        AddTextblock(m_Stack2, "This is item 2", false);
      }
    }
  }

  private async void UpdateItem3(object sender, EventArgs e)
  {
    while (true){
      m_Stack3.Children.Clear();
      for (int i=0; i<10; i++){
        await Task.Delay(1500);
        AddTextblock(m_Stack3, "This is item 3", false);
      }
    }
  }

  private static void StartDelayed(EventHandler handler, int milliseconds)
  {
    DispatcherTimer timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromMilliseconds(milliseconds);
    if (handler != null)
      timer.Tick += new EventHandler(handler);
    timer.Tick += new EventHandler(OnLoadedTimerTick);
    timer.Start();
  } // StartDelayed

  private static void OnLoadedTimerTick(object sender, EventArgs e)
  {
    DispatcherTimer timer = sender as DispatcherTimer;
    if (timer != null)
      timer.Stop();
  } // OnLoadedTimerTick
}

如果您缓慢滚动全景图,就会发现问题:只要将一个项目添加到堆栈面板,全景图就会重新定位到包含添加元素的 PanoramaItem.

The problem can be seen if you scroll slowly the panorama: as soon as one item is added to the stack panel the Panorama will reposition to the PanoramaItem containing the added element.

我的问题是:我做错了什么?如何避免全景图选择panoramaItem?

My question is: what am I doing wrong? How can I avoid the panorama to select the panoramaItem?

推荐答案

一个快速的解决方案是将 StackPanel 封装在一个固定大小的容器中.

A quick solution is to enclose the StackPanel in a fixed size container.

例如

<phone:PanoramaItem Header="Item 1" Name="m_Item1">
    <ScrollViewer Height="1024">
        <StackPanel Orientation="Vertical" Name="m_Stack1"/>
    </ScrollViewer>
</phone:PanoramaItem>

我认为正在发生的是它正在动态调整元素及其容器的大小,从而导致您在水平滚动到下一个全景项目时看到的抖动动作.如果需要,您可以将该 ScrollViewer 的高度绑定到屏幕的高度以实现最佳使用.

What I think is going on is that it is dynamically resizing the element and its container resulting in that jerking motion you see when you scroll horizontally to the next panorama item. And if you want you can bind the height of that ScrollViewer to the height of the screen for optimal use.

这篇关于Windows Phone 8:从后面的代码中将 FrameworkElement 添加到 PanoramaItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆