惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
V
V2EX
博客园 - 【当耐特】
Vercel News
Vercel News
雷峰网
雷峰网
爱范儿
爱范儿
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
NISL@THU
NISL@THU
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
P
Proofpoint News Feed
B
Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
K
Kaspersky official blog
I
InfoQ
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
V
Visual Studio Blog
AI
AI
Schneier on Security
Schneier on Security
B
Blog RSS Feed
T
Tor Project blog
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Cyber Attacks, Cyber Crime and Cyber Security
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
V2EX - 技术
V2EX - 技术
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
Arctic Wolf
Webroot Blog
Webroot Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main

博客园 - 天神一

Windows 8的本地化应用程序清单 WP7开发 Sqlite数据库的使用 解决Unable open the database WP7 真机调试PhotoChooserTask和CameraCaptureTask 解决windows8不能安装ZUNE的问题 软件概要设计 AutoResetEvent详解 解决VS2008 调试启动特别慢 微软WP7本地数据库之Sqlite编程技巧(转) 桥接模式的简单分析 代码的“门面”——模式系列谈之Facade模式(转) SilverLight4:在MVVM架构下实现模式窗口 简析SilverLight的List<T>、ObservableCollection<T>和INotifyPropertyChanged的异同 MVVM架构的简单解析 在MVVM架构下,把EventArgs绑定到Command上【翻译】 XNA 4.0新书:初学者很好的书籍 SilverLight:在MVVM中实现多事件 SilverLight:使用MVVM实现View层在程序运行时自动生成控件并且取得其值 (翻译)在MVVM模式中打开子窗体(Child Window) Windows Phone 7 完全版电子书可以免费下载了
代码滑动panorama-即程序中设置SelectedIndex
天神一 · 2013-07-24 · via 博客园 - 天神一

我们都知道panorama的SelectedIndex属性是只读的,所以通过修改它,在程序滑动panorama似乎不可能。那么是不是就没有办法了呢?
其实我们可以通过设置SelectedItemProperty这个依赖属性来改变SelectedItem的值。
设置方法如下:

pan.SetValue(Panorama.SelectedItemProperty, pan.Items[newIndex]);

虽然可以通过程序改变SelectedItem,但是panorama不会立即更新,我们只需要加一个小技巧,代码如下:

(pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Collapsed;
pan.SetValue(Panorama.SelectedItemProperty, pan.Items[(curIndex + 1) % pan.Items.Count]);
pan.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
(pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Visible;

这样虽然实现了Item切换,却缺少动画效果,那么我们就需要找到相应的item控件,为其添加RenderTransform动画,即动画的target是RenderTransform。
具体实现如下:

private void slidePanorama(Panorama pan)
{
    FrameworkElement panWrapper = VisualTreeHelper.GetChild(pan, 0) as FrameworkElement;
    FrameworkElement panTitle = VisualTreeHelper.GetChild(panWrapper, 1) as FrameworkElement;
    //Get the panorama layer to calculate all panorama items size
    FrameworkElement panLayer = VisualTreeHelper.GetChild(panWrapper, 2) as FrameworkElement;
    //Get the title presenter to calculate the title size
    FrameworkElement panTitlePresenter = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(panTitle, 0) as FrameworkElement, 1) as FrameworkElement;
 
    //Current panorama item index
    int curIndex = pan.SelectedIndex;
 
    //Get the next of next panorama item
    FrameworkElement third = VisualTreeHelper.GetChild(pan.Items[(curIndex + 2) % pan.Items.Count] as PanoramaItem, 0) as FrameworkElement;
 
    //Be sure the RenderTransform is TranslateTransform
    if (!(pan.RenderTransform is TranslateTransform)
        || !(panTitle.RenderTransform is TranslateTransform))
    {
        pan.RenderTransform = new TranslateTransform();
        panTitle.RenderTransform = new TranslateTransform();
    }
 
    //Increase width of panorama to let it render the next slide (if not, default panorama is 480px and the null area appear if we transform it)
    pan.Width = 960;
 
    //Animate panorama control to the right
    Storyboard sb = new Storyboard();
    DoubleAnimation a = new DoubleAnimation();
    a.From = 0;
    a.To = -(pan.Items[curIndex] as PanoramaItem).ActualWidth; //Animate the x transform to a width of one item
    a.Duration = new Duration(TimeSpan.FromMilliseconds(700));
    a.EasingFunction = new CircleEase(); //This is default panorama easing effect
    sb.Children.Add(a);
    Storyboard.SetTarget(a, pan.RenderTransform);
    Storyboard.SetTargetProperty(a, new PropertyPath(TranslateTransform.XProperty));
 
    //Animate panorama title separately
    DoubleAnimation aTitle = new DoubleAnimation();
    aTitle.From = 0;
    aTitle.To = (panLayer.ActualWidth - panTitlePresenter.ActualWidth) / (pan.Items.Count - 1) * 1.5; //Calculate where should the title animate to
    aTitle.Duration = a.Duration;
    aTitle.EasingFunction = a.EasingFunction; //This is default panorama easing effect
    sb.Children.Add(aTitle);
    Storyboard.SetTarget(aTitle, panTitle.RenderTransform);
    Storyboard.SetTargetProperty(aTitle, new PropertyPath(TranslateTransform.XProperty));
 
    //Start the effect
    sb.Begin();
 
    //After effect completed, we change the selected item
    a.Completed += (obj, args) =>
    {
        //Reset panorama width
        pan.Width = 480;
        //Change the selected item
        (pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Collapsed;
        pan.SetValue(Panorama.SelectedItemProperty, pan.Items[(curIndex + 1) % pan.Items.Count]);
        pan.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        (pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Visible;
        //Reset panorama render transform
        (pan.RenderTransform as TranslateTransform).X = 0;
        //Reset title render transform
        (panTitle.RenderTransform as TranslateTransform).X = 0;
 
        //Because of the next of next item will be load after we change the selected index to next item
        //I do not want it appear immediately without any effect, so I create a custom effect for it
        if (!(third.RenderTransform is TranslateTransform))
        {
            third.RenderTransform = new TranslateTransform();
        }
        Storyboard sb2 = new Storyboard();
        DoubleAnimation aThird = new DoubleAnimation() { From = 100, To = 0, Duration = new Duration(TimeSpan.FromMilliseconds(300)) };
 
        sb2.Children.Add(aThird);
        Storyboard.SetTarget(aThird, third.RenderTransform);
        Storyboard.SetTargetProperty(aThird, new PropertyPath(TranslateTransform.XProperty));
        sb2.Begin();
    };
}