zoukankan      html  css  js  c++  java
  • WPF Layout & Image异步加载

    WPF Layout

    在窗体布局中,为了适应不同的分辨率时,我们常常用到神奇的Viewbox控件帮助我们.

    layout1

    XAML:

          <Viewbox>
                <Canvas Width="980" Height="435" x:Name="canvas">
                    <Canvas.Background>
                        <ImageBrush ImageSource="images\hhbanner.jpg"></ImageBrush>
                    </Canvas.Background>
                    
                    <Label Canvas.Left="200"  Content="一口盐水喷死让你还无所畏" FontSize="24"  Name="label1" />
                    <Image  Height="150" Name="image1" Stretch="Fill" Width="200" Source="/WPFLayoutTest;component/images/fzz.jpg" />
                </Canvas>
            </Viewbox>

    如上窗体布局中,Viewbox 里放入了一个Lable,一个Image,当窗体拉伸时,Lable和Image将自动缩放.

    那么如何让窗体放大时,方先生的形象不随着韩同学的形象一起放大呢?

    了解一下WPF Layout System,WPF 提供了一个两个自定义接口(MeasureOverrideArrangeOverride)给用户自定义Layout.
    详细解释参照:

    WPF/Silverlight Layout 系统概述——Measure

    实现如上需求,我们自定义一个Canvas,在重写其ArrangeOverride 方法,当发现子控件是Image时,按照一定比例缩放:

       <Viewbox>
                <my:CustomCanvas Width="980" Height="435" x:Name="canvas">
                    <my:CustomCanvas.Background>
                        <ImageBrush ImageSource="images\hhbanner.jpg"></ImageBrush>
                    </my:CustomCanvas.Background>
                    
                    <Label Canvas.Left="200"  Content="一口盐水喷死让你还无所畏" FontSize="24"  Name="label1" />
                    <Image  Height="150" Name="image1" Stretch="Fill" Width="200" Source="/WPFLayoutTest;component/images/fzz.jpg" />
                </my:CustomCanvas>
            </Viewbox>

    在Window Size Change 时计算还原要的缩放比率

            private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                if (defaultWinSize == Size.Empty)
                    return;
                var newSize = e.NewSize;
                var scaleX = defaultWinSize.Width / newSize.Width;
                var scaleY = defaultWinSize.Height / newSize.Height;
    
                this.canvas.SetScale(scaleX, scaleY);
    
            }
     public class CustomCanvas : Canvas
        {
            private double scaleX = 1;
            private double scaleY = 1;
    
            public void SetScale(double x, double y)
            {
                this.scaleX = x;
                this.scaleY = y;
                this.InvalidateArrange();
            }
    
            /// <summary>
            /// 重写ArrangeOverride 方法,使Image不随着外面的Viewbox缩放而缩放.
            /// </summary>
            /// <param name="arrangeSize"></param>
            /// <returns></returns>
            protected override Size ArrangeOverride(Size arrangeSize)
            {
                Transform scaleTransform = new ScaleTransform(this.scaleX, this.scaleY);
                foreach (UIElement uIElement in base.InternalChildren)
                {
                    if (uIElement != null)
                    {
                        double x = 0.0;
                        double y = 0.0;
                        double left = Canvas.GetLeft(uIElement);
                        if (!DoubleUtil.IsNaN(left))
                        {
                            x = left;
                        }
                        else
                        {
                            double right = Canvas.GetRight(uIElement);
                            if (!DoubleUtil.IsNaN(right))
                            {
                                x = arrangeSize.Width - uIElement.DesiredSize.Width - right;
                            }
                        }
                        double top = Canvas.GetTop(uIElement);
                        if (!DoubleUtil.IsNaN(top))
                        {
                            y = top;
                        }
                        else
                        {
                            double bottom = Canvas.GetBottom(uIElement);
                            if (!DoubleUtil.IsNaN(bottom))
                            {
                                y = arrangeSize.Height - uIElement.DesiredSize.Height - bottom;
                            }
                        }
                        if (uIElement is Image)
                        {
                            uIElement.RenderTransform = scaleTransform;
                        }
                        uIElement.Arrange(new Rect(new Point(x, y), uIElement.DesiredSize));
                    }
                }
                return arrangeSize;
    
            }
        }


    Demo Code: 下载

    Image 异步加载:

    WPF UI 上的东西,不是太容易异步,常用的Backgroud,Dispatch.Invoke 之类的方法,只能对于所操作代码中没有UI相关的才能真的异步,从而不堵住UI线程.

    一下加载很多图片,很容易卡住UI,下面有个方案很好解决了异步加载图片的问题,

    Loading Images Asynchronously in WPF
    http://dotnetlearning.wordpress.com/2011/01/27/loading-images-asynchronously-in-wpf/

    Code 下载

    效果:

    • 可自定义加载的动画,或不使用动画
    • 可自定义加载图片失败时效果

  • 相关阅读:
    最小生成数kruskal算法和prim算法
    图的表示及遍历
    mysql忘记root用户密码重置密码的方式
    dwr2.0版本的demo
    web.xml中不同版本的servlet头以及版本控制
    初学jboss
    Filter学习总结,顺便提及点servlet3.0异步filter和异步监听
    监听器
    问题发现和解决
    linux学习
  • 原文地址:https://www.cnblogs.com/solo/p/2617976.html
Copyright © 2011-2022 走看看