如何判断WPF下窗口判断图片加载完成成了

WPF自适应窗体实现小结 - 吴豪 - 博客园
posts - 29, comments - 6, trackbacks - 0, articles - 0
WPF自适应窗体实现小结
这几天,因工作需要,要对一个小软件进行UI调整。主要内容就是让其能够实现自适应窗体(包括文字和图标),做成像WIN7下的Media Center一样的UI。自适应窗体,顾名思义,就是窗口内容的显示大小能够随着窗口的大小变化而变化。今天我来说说如何用WPF来实现自适应窗体。
首先WPF是微软推出的新一代视窗系统,用来代替MFC。用MFC来实现自适应窗体,需要捕获Resizing事件,然后对窗口内容大小进行逐一调整,还是比较麻烦的。但是WPF不同,因为WPF自带的Layout(WPF布局系统)就支持自适应窗体。
WPF要实现自适应窗体主要靠Grid和DockPanel这2个控件。这2个控件简单来说就是容器,用来承载其它控件。不同的是Grid是定义由行和列组成的灵活网格区域,而DockPanel是定义可水平或垂直排列子元素的区域。
下面我来举个例子说明如何用Grid或DockPanel来实现自适应窗体。
让我们新建一个WPF工程,完成后我们打开对应的XAML文件,可以看到VS已经自动添加了&Grid&&/Grid&这一对标签,下面我就以Grid为例展示如何实现窗体自适应(如果需要使用DockPanel只需把&Grid&&/Grid&换成&DockPanel&&/DockPanel&即可)。
&Window x:Class="Auto_Match_Window.MainWindow"
&&&&&& &xmlns="/winfx/2006/xaml/presentation"
&&&&&& &xmlns:x="/winfx/2006/xaml"
&&&&&& &Title="MainWindow" Height="350" Width="525"&
&&& &Grid&
&&& &/Grid&
下面往Grid里面添加2个控件TextBlock和Button,如下:
&Window x:Class="Auto_Match_Window.MainWindow"
&&&&&& &xmlns="/winfx/2006/xaml/presentation"
&&&&&& &xmlns:x="/winfx/2006/xaml"
&&&&&& &Title="MainWindow" Height="350" Width="525"&
&&& &Grid&
&&&&&&& &TextBlock Text="Hello World!" Margin="100,100,100,100"/&
&&&&&&& &Button Content="Button" Margin="100,120,100,100"/&
&&& &/Grid&
注意:这里不能给TextBlock和Button定义高度和宽度,因为这样会把控件的高度和宽度定死,结果就是不能随着窗口大小的变化而变化。那要怎么调整控件的初始大小呢?用Margain!!Margain不是只能调整位置,它也可以调整控件大小哦。
让我们来看看效果怎样:
通过上面2张图,我们可以看到控件确实随着窗口大小的变化而变化,但是我们又发现无论是TextBlock还是Button的文字并没有随着窗口变化,这是为什么呢?那是因为Grid和DockPanel不支持文本的自动变化。
&&& 那文本是不是就没办法自动变化了呢?放心WPF提供另外一个控件Viewbox,用于支持文本变化。让我们修改一下刚才的代码,如下:
&Window x:Class="Auto_Match_Window.MainWindow"
&&&&&& &xmlns="/winfx/2006/xaml/presentation"
&&&&&& &xmlns:x="/winfx/2006/xaml"
&&&&&& &Title="MainWindow" Height="350" Width="525"&
&&& &Grid&
&&&&&&& &Viewbox VerticalAlignment="Top"&
&&&&&&&&&&& &TextBlock Text="Hello World!" VerticalAlignment="Top"/&
&&&&&&& &/Viewbox&
&&&&&&& &Viewbox VerticalAlignment="Bottom"&
&&&&&&& &Button Content="Button"/&
&&&&&&& &/Viewbox&
&&& &/Grid&
效果如下:
如果加了Viewbox,画面的布局可能比较难以调整,这个时候就需要用到Width和Height这2个属性了。读者可能有疑问了,为什么不加Viewbox只用Grid或DockPanel不能指定Width和Height,而Viewbox就可以。那是因为Viewbox其实是靠stretch这个属性实现文本的自动变化,这也意味着Viewbox是通过拉伸或平铺来达到缩放文本的效果,就好比位图。而Grid和DockPanel就好比矢量图。
代码如下:
&Window x:Class="Auto_Match_Window.MainWindow"
&&&&&& &xmlns="/winfx/2006/xaml/presentation"
&&&&&& &xmlns:x="/winfx/2006/xaml"
&&&&&& &Title="MainWindow" Height="350" Width="525"&
& &&&Grid&
&&&&&&& &Viewbox&
&&&&&&&&&&& &TextBlock Text="Hello World!" Margin="100,100,100,100"/&
&&&&&&& &/Viewbox&
&&&&&&& &Viewbox&
&&&&&&& &Button Content="Button" Margin="100,120,100,100" Height="92" Width="118"/&
&&&&&&& &/Viewbox&
&&& &/Grid&
好了,让我们来总结一下:
1、& WPF采用Grid和DockPanel来实现窗体自适应,通过控件的Margain属性来调整控件的起始位置和大小,不能使用Height和Width属性;
2、& 如果要实现文本自动变化,采用Viewbox控件,可以使用Height和Width来调整控件大小;
3、& 想偷懒的话,可以把MainWindow的最外面一层Grid放入Viewbox中,这样只需稍微调整一下某些控件的布局即可达到整个窗体的自适应效果。
这是我第一次写博客,写的不好,请大家体谅。WPF 制作聊天窗口获取历史聊天记录 - 一 定 会 去 旅 行 - 博客园
腾讯从QQ2013版起开始在聊天记录里添加了历史记录查看功能,个人聊天窗口可以点击最上边的&查看历史消息&,而群组里的未读消息可以通过滚动鼠标中键或者拖动滚动条加载更多消息,那这个用wpf怎么实现呢?
我用Scrollviewer和RichTextBox做了一个简陋尝试,真的是太陋了,大家戴好眼镜了哈。现在开始:
首先是前台的陋XAML:
&Window x:Class="testFlowDocument.MainWindow"
xmlns="/winfx/2006/xaml/presentation"
xmlns:x="/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"&
&ScrollViewer x:Name="sv_richtextbox" Background="Transparent" PreviewMouseLeftButtonUp="sv_richtextbox_PreviewMouseLeftButtonUp"
PreviewMouseWheel="sv_richtextbox_PreviewMouseWheel"
VerticalScrollBarVisibility="Auto" ScrollChanged="sv_richtextbox_ScrollChanged"&
&RichTextBox IsReadOnly="True" x:Name="RichTextBoxMessageHistory" BorderBrush="#B7D9ED"
Margin="3,3,3,0" Background="Silver" /&
&/ScrollViewer&
&Button Name="previousadd" Content="前加" Height="30" Width="100" VerticalAlignment="Bottom" HorizontalAlignment="Left" Click="previousadd_Click"&&/Button&
&Button Name="clearadd" Content="清空" Height="30" Width="100" VerticalAlignment="Bottom" Click="clearadd_Click"&&/Button&
&Button Name="add20" Content="加20条" Height="30" Width="50" VerticalAlignment="Bottom" Margin="0,0,110,0" HorizontalAlignment="Right" Click="add20_Click"&&/Button&
&Button Name="lastadd" Content="后加" Height="30" Width="100" VerticalAlignment="Bottom" HorizontalAlignment="Right" Click="lastadd_Click"&&/Button&
&在基本布局里添加了一个Scrollviewer包含RichTextBox,另外添加了4个Button控件来添加简单数据。previousadd往最上端插入数据,lastadd从底部添加数据。add20快速添加20条数据使之出现滚动条。
好了,下面是后台陋CS实现:
using System.Collections.G
using System.L
using System.T
using System.W
using System.Windows.C
using System.Windows.D
using System.Windows.D
using System.Windows.I
using System.Windows.M
using System.Windows.Media.I
using System.Windows.N
using System.Windows.S
namespace testFlowDocument
/// &summary&
/// MainWindow.xaml 的交互逻辑
/// &/summary&
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
int i = 0;
private void previousadd_Click(object sender, RoutedEventArgs e)
addmessage(1);
/// &summary&
/// 插入数据
/// &/summary&
void addmessage(int pagesize)
for (int j = 0; j & j++)
vScrollposition = sv_richtextbox.ExtentH
Paragraph pggethistoryNo = new Paragraph();
pggethistoryNo.Background = Brushes.LightB
pggethistoryNo.Margin = new Thickness(0, 5, 60, 0);
TextBlock tblockgethistoryNo = new TextBlock();
tblockgethistoryNo.Text = i.ToString();
tblockgethistoryNo.Foreground = Brushes.B
pggethistoryNo.Inlines.Add(tblockgethistoryNo);
if (RichTextBoxMessageHistory.Document.Blocks != null && RichTextBoxMessageHistory.Document.Blocks.Count & 0)
{//判断是否存在数据了
RichTextBoxMessageHistory.Document.Blocks.InsertBefore(RichTextBoxMessageHistory.Document.Blocks.FirstBlock, pggethistoryNo);
{//若不存在,第一条要加入而非插入
RichTextBoxMessageHistory.Document.Blocks.Add(pggethistoryNo);
isEnd = false;
bool isEnd = false;//是否滚动到底部
double vScrollposition = 0;//当前接收到的所有文本内容高度(包括历史消息)
private void sv_richtextbox_ScrollChanged(object sender, ScrollChangedEventArgs e)
if (e.ViewportHeightChange & 0)
if (isEnd == true)
{//判断是否是从底部添加数据
if (sv_richtextbox.ScrollableHeight == sv_richtextbox.VerticalOffset)
{//判断滚动条是否在最底部
sv_richtextbox.ScrollToEnd();
{//定位到上次位置
double changevScrollHeight = sv_richtextbox.ExtentHeight - vS
if (changevScrollHeight & 0)
sv_richtextbox.ScrollToVerticalOffset(e.ViewportHeightChange + changevScrollHeight);
sv_richtextbox.ScrollToVerticalOffset(e.ViewportHeightChange);
private void lastadd_Click(object sender, RoutedEventArgs e)
Paragraph pggethistoryNo = new Paragraph();
pggethistoryNo.Background = Brushes.LightG
pggethistoryNo.Margin = new Thickness(60, 5, 0, 0);
TextBlock tblockgethistoryNo = new TextBlock();
tblockgethistoryNo.Text = i.ToString();
tblockgethistoryNo.Foreground = Brushes.B
pggethistoryNo.Inlines.Add(tblockgethistoryNo);
RichTextBoxMessageHistory.Document.Blocks.Add(pggethistoryNo);
isEnd = true;
private void clearadd_Click(object sender, RoutedEventArgs e)
RichTextBoxMessageHistory.Document.Blocks.Clear();
private void Window_Loaded(object sender, RoutedEventArgs e)
RichTextBoxMessageHistory.Document.Blocks.Clear();
private void add20_Click(object sender, RoutedEventArgs e)
addmessage(20);
private void sv_richtextbox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
if (e.Delta & 0)
isAddMessage();
private void sv_richtextbox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
isAddMessage();
void isAddMessage()
double offi = sv_richtextbox.VerticalO
if (offi == 0)
double Maxinum = sv_richtextbox.ScrollableH
if (Maxinum == 0)
vScrollposition = sv_richtextbox.ExtentH
addmessage(10);
RichTextBoxMessageHistory.Focus();
向RichTextBox控件追加内容,可以用Document.Blocks.Add(Block item)方法。
而向RichTextBox插入内容,用的是Document.Blocks.InsertBefore(Block nextSibling, Block newItem)方法,其中nextSibling指的是将要被插入的位置,newItem指的是将要插入的新内容。而获取历史聊天记录后,我们可以用此方法往最上端插入数据。所以,此处我们可以写作&RichTextBoxMessageHistory.Document.Blocks.InsertBefore(RichTextBoxMessageHistory.Document.Blocks.FirstBlock, pggethistoryNo);其中pggethistoryNo是新定义的内容;
其实今天的主角是&拖动滚动条和滚动鼠标键加载数据&,而幕后的英雄是ScrollChanged事件。当我们拖动滚动条和滚动鼠标键加载出新数据时,会有一个滚动条定位的问题,有人说收到新消息时应该跳到新消息处虽新的聊天自动往下滚动,即总在最底端;有人说当你正在看历史消息时如果突然来了一条消息就跳到最底端那还得再重新找刚才的位置,让人很抓狂;还有人说当拖动加载出新消息时如果滚动条呆在新加载出内容的顶端,还得再去手动找刚才读到的位置也是一件烦人眼珠子的事。能不能做一件完美的事情同时满足三者呢?有时候猜不到结局就勇敢的去做吧~~
1、自动滚到最底部:&sv_richtextbox.ScrollToEnd();
2,3、定位在某位置:&sv_richtextbox.ScrollToVerticalOffset(double offset);
如何判断是从最上边插入的还是从最下边添加的呢?我们设置了参数isEnd来判断,true表示滚到最下端。如何判断添加新消息时滚动条是否在最下边呢?用sv_richtextbox.ScrollableHeight == sv_richtextbox.VerticalOffset判断。当滚动条有变化(位置或大小)时ScrollChanged事件会捕获到,我们就在该事件里做判断。
需要特别注意:很多人说自己在Scrollviewer中鼠标事件无效,提醒一下,在Scrollviewer控件中捕获不到MouseUp等事件,但可以捕获到PreviewMouseUp等事件。
附两张陋图:
本文博客园地址:
到此为止,我要说的说完了,谢谢大家捧场。。2017年6月 总版技术专家分月排行榜第三
2017年8月 多媒体开发大版内专家分月排行榜第一2017年8月 .NET技术大版内专家分月排行榜第一2017年7月 多媒体开发大版内专家分月排行榜第一2017年7月 .NET技术大版内专家分月排行榜第一2017年6月 .NET技术大版内专家分月排行榜第一2017年5月 多媒体开发大版内专家分月排行榜第一2017年4月 多媒体开发大版内专家分月排行榜第一2016年1月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年11月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年10月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年9月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年7月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年6月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年3月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年1月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年12月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年11月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年10月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年9月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年8月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年7月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一
2017年6月 总版技术专家分月排行榜第三
2017年8月 多媒体开发大版内专家分月排行榜第一2017年8月 .NET技术大版内专家分月排行榜第一2017年7月 多媒体开发大版内专家分月排行榜第一2017年7月 .NET技术大版内专家分月排行榜第一2017年6月 .NET技术大版内专家分月排行榜第一2017年5月 多媒体开发大版内专家分月排行榜第一2017年4月 多媒体开发大版内专家分月排行榜第一2016年1月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年11月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年10月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年9月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年7月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年6月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年3月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年1月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年12月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年11月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年10月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年9月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年8月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年7月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一
2017年6月 总版技术专家分月排行榜第三
2017年8月 多媒体开发大版内专家分月排行榜第一2017年8月 .NET技术大版内专家分月排行榜第一2017年7月 多媒体开发大版内专家分月排行榜第一2017年7月 .NET技术大版内专家分月排行榜第一2017年6月 .NET技术大版内专家分月排行榜第一2017年5月 多媒体开发大版内专家分月排行榜第一2017年4月 多媒体开发大版内专家分月排行榜第一2016年1月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年11月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年10月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年9月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年7月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年6月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年3月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2015年1月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年12月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年11月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年10月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年9月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年8月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一2014年7月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第一
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。

我要回帖

更多关于 js判断iframe加载完成 的文章

 

随机推荐