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

推荐订阅源

小众软件
小众软件
N
News and Events Feed by Topic
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
The Cloudflare Blog
H
Heimdal Security Blog
Schneier on Security
Schneier on Security
Engineering at Meta
Engineering at Meta
Google Online Security Blog
Google Online Security Blog
宝玉的分享
宝玉的分享
AI
AI
The GitHub Blog
The GitHub Blog
MongoDB | Blog
MongoDB | Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
S
Security @ Cisco Blogs
H
Hacker News: Front Page
F
Fortinet All Blogs
博客园_首页
S
Secure Thoughts
N
News and Events Feed by Topic
P
Proofpoint News Feed
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
Spread Privacy
Spread Privacy
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Hugging Face - Blog
Hugging Face - Blog
Hacker News: Ask HN
Hacker News: Ask HN
C
CXSECURITY Database RSS Feed - CXSecurity.com
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
L
LINUX DO - 最新话题
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
Know Your Adversary
Know Your Adversary
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Scott Helme
Scott Helme
P
Privacy & Cybersecurity Law Blog
S
Securelist
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
O
OpenAI News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
PCI Perspectives
PCI Perspectives
L
LangChain Blog
雷峰网
雷峰网
Security Archives - TechRepublic
Security Archives - TechRepublic
V2EX - 技术
V2EX - 技术

博客园 - Haozes

新Blog 拼写检查算法 Golang 版 Windbg 离线调试.Net 程序入门 (译)你必须知道的位运算技巧 Low Level Bit Hacks You Absolutely Must Know Windows 下 命令行增强工具 几篇文章了解编译原理 WPF Binding Validation 数据验证 WPF 实现Loading效果 推荐一个.NET 命令行参数Parser 库 常用开发工具介绍 使用.Net Memory Profiler 分析.Net程序内存泄露 使用Mdbg.exe 调试.Net 程序 WPF 多语言方案 .Net 2 Tip :捕获CSE和Thread.Timer与Thread.Sleep比较 使用CSharp Driver操作Mongodb介绍 使用Python操作MSSQL数据库. 运行.Net4.0程序是否要安装之前的.Net版本 javascript Disable <div> or other tag in Other Browser like FF,Chrome Delphi 无类型参数传递动态数组和静态数组
WPF Layout & Image异步加载
Haozes · 2012-08-01 · via 博客园 - Haozes

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 下载

效果:

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