从数据库读取图片发生“无效的参数”异常

介绍 我发现对于很多人来说,当从数据库里载入一张图片然后重新创建成一张图片显示的话会有这样一个问题—-当他们尝试重新创建新的图片的时候,会抛出一个“无效的参数”异常 因此,本文介绍该异常如何产生。并且我希望未来当我或是你发生这个错误的时候还能有所帮助。。 背景 存储图片到数据库里面是一个很有效的想法。很多人在一些场合都会这样做。的确,这是一个很好的想法。在图片很小的情况下,或者图片不是太多。在这两种情况下,当你需要图片的时候,你会实时去加载它们。而当你不需要的时候如果从数据库里加载图片会浪费很多带宽。并使得你的程序有一些慢。 但问题是这种方法也很容易发生错误。–尤其是你使用字符串连接,然后组合到你的SQL语句里面—并且这个错误只有当你打算使用存储的信息的时候才会发生。然后,看起来似乎是你的读取代码写错了—不可能—它是正常的。我在其他地方都可以的。。 从数据库里加载图片 重数据库里读取一张图片然后转换成图片显示是很简单的。 using (SqlConnection con = DBAccess.DBCon) { using (SqlCommand cmd = new SqlCommand("SELECT picture FROM Pictures WHERE Id=@ID", con)) { cmd.Parameters.AddWithValue("@ID", Id); SqlDataReader reader = cmd.ExecuteReader(); if (reader.Read()) { byte[] data = (byte[])reader["Picture"]; using (MemoryStream stream = new MemoryStream(bytes)) { myImage = new Bitmap(stream); } } } } 但是-如果data因为一些原因不是有效的图片,那么这一行 myImage = new Bitmap(stream); 将会抛出一个异常—无效的参数 只有当你真正看了从数据库里返回到data里的数据-而不是简单的瞄了一眼调试器,你才能注意到是什么原因。。 {byte[21]} [0] 83 [1] 121 [2] 115 [3] 116 [4] 101 [5] 109 [6] 46 [7] 68 [8] 114 [9] 97 [10] 119 [11] 105 [12] 110 [13] 103 [14] 46 ... 它看起来不像是错的,所以它可能就是你想要的。-虽然21字节是一个很大的线索:你的图片可能只有21字节长?那图片可真小。。 但是,上面的是可以读懂的。。稍微练习一下。。每个字节是一个ASCII码。。 "83" is an uppercase 'S' "121" is an lowercase 'y' "115" is an lowercase 's' "116" is an lowercase 't' "101" is an lowercase 'e' "109" is an lowercase 'm' "46" is a '.' "68" is an uppercase 'D' "114" is an lowercase 'r' "97" is an lowercase 'a' "119" is an lowercase 'w' "105" is an lowercase 'i' "110" is an lowercase 'n' "103" is an lowercase 'g' "46" is an lowercase '.' ... 简而言之,你从数据库里得到的数据是一个人类可以读懂的字符串,意思是是 ...

2012-09-27 · 2 min · bystander

C#使用Graphics创建饼图

介绍 这个程序是使用C#中的Graphics来创建一个饼图的,我已经尽我所能写的很好了。如果你有任何建议可以分享给我,这样我也能从中学习。 使用代码 最近我迷上了Graphics类。我仅仅体验了一下Graphics的DrawPie() 和FillPie() 方法。 最为一个简单的Demo,我创建一个有着五个文本框的窗体,一个按钮,一个图片框。一会我就把饼图画在图片框里 在创建一个饼图之前,我们头脑里要有这个意识。我们不能创建一个不符合常规的圆,创建圆我们需要度数信息。 为了转换度数。我们首先把给定的值做个求和。然后得出文本框里所有值的和。然后呢。用每个值除以总值再乘以360度。 代码如下: int i1 = Int32.Parse(textBox1.Text); int i2 = Int32.Parse(textBox2.Text); int i3 = Int32.Parse(textBox3.Text); int i4 = Int32.Parse(textBox4.Text); int i5 = Int32.Parse(textBox5.Text); float total = i1 + i2 + i3 + i4 + i5 ; float deg1 = (i1 / total) * 360; float deg2 = (i2 / total) * 360; float deg3 = (i3 / total) * 360; float deg4 = (i4 / total) * 360; float deg5 = (i5 / total) * 360; 值转换完毕后。我们可以创建Graphics类的实例了。 Graphics graphics = pictureBox1.CreateGraphics(); 然后我们需要创建一个矩形区域,在这个矩形区域里绘制饼图。 Rectangle rect = new Rectangle(0, 0, 150, 150); 前两个参数定义了矩形左上角的坐标,后两个分别定义了举行的宽和高。 为了能够比较清晰的看出饼图各部分的比例。我们需要创建五个笔刷。 Brush brush1 = new SolidBrush(Color.Red); Brush brush2 = new SolidBrush(Color.Blue); Brush brush3 = new SolidBrush(Color.Maroon); Brush brush4 = new SolidBrush(Color.Navy); Brush brush5 = new SolidBrush(Color.YellowGreen); graphics.Clear(pictureBox1.BackColor); 现在我们可以开始创建我们的饼图了。graphics.FillPie();方法接受四个参数 笔刷,用来填充扇形 矩形:饼图将被创建的区域。 开始角度:饼部分的开始角度 覆盖角度:饼部分扫过的角度 一般来说graphics.FillPie();方法并不是创建一个完全的饼图,而是创建饼图的一个扇形部分,我们会创建一系列的扇形最终看起来像是一个饼图。 ...

2012-09-27 · 2 min · bystander

AvalonDock 2.0入门指南第一部分

AvalonDock 2.0可以用来为WPF创建一个类似Visual Studio的界面,深入理解如何使用AvalonDock进行开发是很重要的。 在这个入门指南里,我将演示如何开始使用AvalonDock,下面的文章都是基于2.0版本的。并且不能用于早期的版本。 AvalonDock是一个组合的布局模型,很多的控件都在视图上显示,一个DockingManager 类也显示在停靠区,用于可以拖拽文档和工具。 从下面这个截图中我们可以理解AvalonDock组件 DockingManager 这是AvalonDock中的核心控件,它将包含的窗格排序,处理飞出的窗格,还有浮动的窗口。在上面这个图中,DockingManager 对象包含了所有空间(WPF控件),从顶部的工具栏到底部的状态栏都算。同时。DockingManager 也可以处理保存和恢复布局。 LayoutPanel 这个面板用来管理在一个方向上的子窗口(通过Orientation属性来选择方向),并且在它们之间添加了一个大小调节控件,在一个Orientation属性是Horizontal(水平)的LayoutPanel 上,排列了三个窗格。一个LayoutAnchorablePane在左,一个LayoutDocumentPane在中间。一个LayoutDockablePane在右边。 LayoutDockablePane 这个布局元素包含一个LayoutAnchorable对象的集合。通过它用来管理想TabControl这样的控件,在上面的截图中,LayoutDockablePanes是在左边的’Strumenti’ 和 ‘Progetti’ (工具和项目) 和在右边的’Classi’ 和 ‘Proprieta’’ (类视图和属性视图)的容器,一个LayoutDockablePane可以自动隐藏,就像’Errori’(错误)和’Lista Azioni’(操作列表) and ‘Uscita’(输出)。并且LayoutDockablePane可以被拖动到DockingManager上,成为一个浮动窗口或者附着到它的父控件DockingManager的边缘上。 LayoutDocumentPane 通常包含文档(DocumentContent类型)的一种窗格,但是其实也可以包含像上面提到的工具视图和类视图这样的DockableContents。在一个文档里。LayoutDocumentPane 被放置在ResizingPanel(水平方向)里。ResizingPanel则是上卖弄提到的在两个DockablePane中间的区域。注意。文档窗格是不能被移动的。 LayoutAnchorable 一个停靠内容,是软件控件的容器,总是被包含在一个窗格里(LayoutAnchorablePane或是LayoutDocumentPane),在截图里。LayoutAnchorable是一类对象(包含一个SharpDevelop对象),工具对象,但是错误窗口(它处于自动隐藏状态,被好办在一个自动隐藏窗格里)不是。LayoutAnchorable就像它名字所暗示的那样。可以被从他的容器窗格里拖走。然后重新放置在一个存在的窗格里。或者是放置在父DockingManager的边缘,或者是放置在一个浮动窗口里(LayoutAnchorableFloatingWindow)。 LayoutDocument 是一个仅可以被寄宿到LayoutDocumentPane的内容。它是一个特殊的内容,因为不能被停靠到边缘。仅能被放置到LayoutDocumentPane里。或者浮动在一个LayoutDocumentFloatingWindow窗口里。在途中,DocumentContent对象是program.cs’ 或 ‘MainForm.cs’ 文件视图 **LayoutFloatingWindow **,是一个包含内容的窗口,当被拖动到一个DockingManager上面的时候,LayoutFloatingWindow(LayoutAnchorableFloatingWindow和LayoutDocumentFloatingWindow继承自他)集成在Window,总是包含一个窗格(LayoutAnchorablePane或是LayoutDocumentPane),窗格包含更多的内容(LayoutAnchorable或LayoutDocument),当用户对一个内容或是DockablePane执行拖拽,或者直接手工使用代码调用LayoutContent.Float()方法 LayoutFloatingWindow就被直接从DockingManager创建出来了。 LayoutPane 一个基类,LayoutDockablePane和LayoutDocumentPane继承自它。它为他们提供了一些共有的属性和方法。 LayoutContent 是LayoutAnchorable 和LayoutAnchorable类的父类。提供了共有的属性和方法。 理解布局元素是一些属于布局模型的类而不是属于视图是很重要的。因为,他们不是继承自FrameworkElement类,取而代之。AvalonDock包含了另一些类来展示这些组件的视图。这些类通常被命名为相关联的类名+Control字串。举个例子,在布局里创建的LayoutAnchorable创建了一个LayoutAnchorableControl(继承自FrameworkElement的类),并且绑定了LayoutAnchorableControl.Model 到这个LayoutAnchorable对象上。 每一个被创建的视图控件总是有着Model属性的布局元素。因此,重新设计一个相关视图控件的样式是可以的。 为了开始创建一个新的.net 4/.net 4.5的解决方案。并且添加对AvalonDock.dll的引用(可以直接添加也可以使用NuGet),然后添加AD命名空间到MainWindow.xaml中。 在根Grid下放置DockingManager组件和一个简单的布局。 <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonDock="http://avalondock.codeplex.com" Title="MainWindow" Height="434" Width="684"> <Grid> <avalonDock:DockingManager x:Name="dockingManager"> <avalonDock:LayoutRoot> <avalonDock:LayoutPanel Orientation="Horizontal"> <avalonDock:LayoutDocumentPane/> <avalonDock:LayoutAnchorablePane DockWidth="150"> <avalonDock:LayoutAnchorable Title="Sample Tool Pane"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> </avalonDock:LayoutPanel> <avalonDock:LayoutRoot.LeftSide> <avalonDock:LayoutAnchorSide> <avalonDock:LayoutAnchorGroup> <avalonDock:LayoutAnchorable Title="Autohidden Content"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorGroup> </avalonDock:LayoutAnchorSide> </avalonDock:LayoutRoot.LeftSide> </avalonDock:LayoutRoot> </avalonDock:DockingManager> </Grid> </Window> DockingManager是AvalonDock的核心类,他的责任就是创建管理布局。布局被定义成一个ILayoutElement的树。树的根由LayoutRoot类指定。LayoutRoot由一些基本的子树来构成。。 1.根面板的 根属性指向主 LayoutPanel,也是LayoutRoot的内容属性。 2.大体上讲,RightSide/LeftSide/TopSide/BottonSide是LayoutAnchorGroup对象的集合属性,他们表示了停靠管理器的四个边。停靠管理器的锚通常是隐藏的。当用户移动鼠标到这些区域的时候。就会在自动隐藏的窗口里显示出来。 3.FloatingWindows属性是FloatingWindow的集合。一个浮动窗口当用户拖动一个窗格(LayoutAnchorable或是LayoutDocument)的时候就被创建出来,这个集合可以被AvalonDock自动更新,但是用户依然可以通过调用LayoutContent的Float()方法来创建一个浮动窗口。 Hidden是一个Anchorable(停靠)对象的集合。默认情况下,当用户点击一个LayoutAnchorable对象的关闭按钮,AvalonDock隐藏它:通过从布局里移除停靠元素,并且把他放入Hidden集合,当用户想要再一次显示的时候,AD又把这个内容从隐藏集合里删除重新显示在他被隐藏的那个窗格里。 当使用布局树的时候,程序员可以创建任何复杂的界面,LayoutAnchorablePane的DockWidth和DockHeight属性可以被用来设置窗格的初始宽度和高度。而LayoutDocumentPane类通常则填满可用的空间。AvalonDock管理内容元素的宽度和高度以使得可以使用所有的可用空间。因此如果一个LayoutAnchorablePane被放置在一个LayoutPanel里,为LayoutAnchorablePane使用一个固定尺寸而为LayoutDocumentPane使用一个比例长度。也就是说为停靠对象使用了比例长度。 一个LayoutDocumentGroup/ LayoutAnchorableGroup类可以被用来包含更多的LayoutDocumentPane/ LayoutAnchorablePane,举个例子,让我们来改变上面的例子来实现更复杂的例子。 <Window x:Class="AvalonDock2Tutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonDock="http://avalondock.codeplex.com" Title="MainWindow" Height="350" Width="525"> <Grid> <avalonDock:DockingManager x:Name="dockingManager"> <avalonDock:LayoutRoot> <avalonDock:LayoutPanel Orientation="Horizontal"> <avalonDock:LayoutDocumentPaneGroup> <avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocument Title="Doc1"> <TextBox/> </avalonDock:LayoutDocument> <avalonDock:LayoutDocument Title="Doc2"> <TextBox/> </avalonDock:LayoutDocument> </avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocument Title="Doc3"> <TextBox/> </avalonDock:LayoutDocument> </avalonDock:LayoutDocumentPane> </avalonDock:LayoutDocumentPaneGroup> <avalonDock:LayoutAnchorablePaneGroup DockWidth="150" Orientation="Vertical"> <avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorable Title="Tool 1"> <TextBox/> </avalonDock:LayoutAnchorable> <avalonDock:LayoutAnchorable Title="Tool 2"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorable Title="Tool 3"> <TextBox/> </avalonDock:LayoutAnchorable> <avalonDock:LayoutAnchorable Title="Tool 4"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> </avalonDock:LayoutAnchorablePaneGroup> </avalonDock:LayoutPanel> <avalonDock:LayoutRoot.LeftSide> <avalonDock:LayoutAnchorSide> <avalonDock:LayoutAnchorGroup> <avalonDock:LayoutAnchorable Title="Autohidden Content"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorGroup> </avalonDock:LayoutAnchorSide> </avalonDock:LayoutRoot.LeftSide> </avalonDock:LayoutRoot> </avalonDock:DockingManager> </Grid> </Window> 运行这个工程你就可以重新排列内容了。移动他们到浮动窗口。为了更加熟悉AvalonDock,我建议你多试几次,然后重新排列内容实现更复杂的布局。 ...

2012-09-26 · 1 min · bystander

C#编写youtube下载器

介绍 本文将会暂时如何仅仅使用C#来下载youtub视频,代码简单也容易理解,每个人都可以把它整合到自己的工程项目里。 我没有使用任何第三方的库来完成这段代码,你所要做的仅仅是把两个.cs文件整合进你的项目里。 使用代码 这个工程里有两个主要的类 YouTubeVideoQuality Class(youtube视频质量类) public class YouTubeVideoQuality { /// <summary> /// Gets or Sets 文件名 /// </summary> public string Videotitle: { get; set; } /// <summary> /// Gets or Sets 文件扩展 /// </summary> public string Extention { get; set; } /// <summary> /// Gets or Sets 文件地址 /// </summary> public string DownloadUrl { get; set; } /// <summary> /// Gets or Sets 视频地址 /// </summary> public string VideoUrl { get; set; } /// <summary> /// Gets or Sets 文件大小 /// </summary> public Size Dimension { get; set; } public override string ToString() { return Extention + " File " + Dimension.Width + "x" + Dimension.Height; } public void SetQuality(string Extention, Size Dimension) { this.Extention = Extention; this.Dimension = Dimension; } } YouTubeDownloader Class(youtube下载类) public class YouTubeDownloader { public static List<YouTubeVideoQuality> GetYouTubeVideoUrls(params string[] VideoUrls) { List<YouTubeVideoQuality> urls = new List<YouTubeVideoQuality>(); foreach (var VideoUrl in VideoUrls) { string html = Helper.DownloadWebPage(VideoUrl); string title: = GetTitle(html); foreach (var videoLink in ExtractUrls(html)) { YouTubeVideoQuality q = new YouTubeVideoQuality(); q.VideoUrl = VideoUrl; q.Videotitle: = title; q.DownloadUrl = videoLink + "&title=" + title; if (getQuality(q)) urls.Add(q); } } return urls; } private static string GetTitle(string RssDoc) { string str14 = Helper.GetTxtBtwn(RssDoc, "'VIDEO_TITLE': '", "'", 0); if (str14 == "") str14 = Helper.GetTxtBtwn(RssDoc, "\"title\" content=\"", "\"", 0); if (str14 == "") str14 = Helper.GetTxtBtwn(RssDoc, "&title=", "&", 0); str14 = str14.Replace(@"\", "").Replace("'", "'").Replace( "\"", """).Replace("<", "<").Replace( ">", ">").Replace("+", " "); return str14; } private static List<string> ExtractUrls(string html) { html = Uri.UnescapeDataString(Regex.Match(html, "url_encoded_fmt_stream_map=(.+?)&", RegexOptions.Singleline).Groups[1].ToString()); MatchCollection matchs = Regex.Matches(html, "url=(.+?)&quality=(.+?)&fallback_host=(.+?)&type=(.+?)&itag=(.+?),", RegexOptions.Singleline); bool firstTry = matchs.Count > 0; if (!firstTry) matchs = Regex.Matches(html, "itag=(.+?)&url=(.+?)&type=(.+?)&fallback_host=(.+?)&sig=(.+?)&quality=(.+?),{0,1}", RegexOptions.Singleline); List<string> urls = new List<string>(); foreach (Match match in matchs) { if (firstTry) urls.Add(Uri.UnescapeDataString(match.Groups[1] + "")); else urls.Add(Uri.UnescapeDataString(match.Groups[2] + "") + "&signature=" + match.Groups[5]); } return urls; } private static bool getQuality(YouTubeVideoQuality q) { if (q.DownloadUrl.Contains("itag=5")) q.SetQuality("flv", new Size(320, 240)); else if (q.DownloadUrl.Contains("itag=34")) q.SetQuality("flv", new Size(400, 226)); else if (q.DownloadUrl.Contains("itag=6")) q.SetQuality("flv", new Size(480, 360)); else if (q.DownloadUrl.Contains("itag=35")) q.SetQuality("flv", new Size(640, 380)); else if (q.DownloadUrl.Contains("itag=18")) q.SetQuality("mp4", new Size(480, 360)); else if (q.DownloadUrl.Contains("itag=22")) q.SetQuality("mp4", new Size(1280, 720)); else if (q.DownloadUrl.Contains("itag=37")) q.SetQuality("mp4", new Size(1920, 1280)); else if (q.DownloadUrl.Contains("itag=38")) q.SetQuality("mp4", new Size(4096, 72304)); else return false; return true; } } 有趣的地方 使用这个代码,你可以根据你的网速来选择不同品质的视频来下载 ...

2012-09-25 · 2 min · bystander

.net显示网络连接状态图标

效果图: 介绍 越来越多的软件要通过连接互联网来执行一些业务层的业务操作,比如调用web services服务,获取数据等等。 通常你可能希望知道当前你的网络连接是不是真的连上了,当然有很多种方法可以做到,比如,你可以查看System.Net 命名空间中的NetworkInterface 的状态,但是有这以太网连接并不表示你的连接真的可以用。 本文将会展示一种方法,该方法在程序的状态栏StatusStrip 显示一个简单的图标来指示是不是真的连接到了互联网。 使用代码 最简单的我们会想到使用一个Timer来进行http-get请求来判断一个特定的网页是否可用。 当然这种方法下,我们最应该考虑的就是请求不能阻塞UI线程,因此,我将使用一个BackgroundWorker 对象来进行get请求,BackgroundWorker 对象声明了DoWork方法。该方法定义了一个事件句柄,该句柄传递一个DoWorkEventArgs 类来将事件的处理结果返回到UI线程,因此,你不必与任何的UI元素进行交互,因为它运行在一个独立的线程里。 private void InitializeComponent() { // Background Worker this._worker = new BackgroundWorker(); this._worker.WorkerReportsProgress = false; this._worker.WorkerSupportsCancellation = false; this._worker.DoWork += new DoWorkEventHandler(this.BackgroundWorker_DoWork); this._worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted); // Timer this._updateTimer = new Timer(); this._updateTimer.Enabled = !this.DesignMode; // Enabled when not in design mode this._updateTimer.Tick += delegate { this.OnTick(); }; } private void OnTick() { if (this.DesignMode) return; // Stop the timer while the process is running this._updateTimer.Enabled = false; // Disable so we get the grayed-out look this.Enabled = false; this.Invalidate(); // Execute the Ping Query on a separate thread... this._worker.RunWorkerAsync(); } 这个查询很简单,我执行简单的HttpWebRequest 来请求一个必然是可用的网页。比如微软的主页或是Google的主页。通过这样,我们就能知道是不是真的连接上了互联网。 private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { try { // Create an HTTP Web request // to an Uri that's always available. HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(this._alwaysAvailableUrl); // Perform GET HttpWebResponse response = (HttpWebResponse) request.GetResponse(); if (HttpStatusCode.OK == response.StatusCode) { // HTTP = 200, close the request and return true response.Close(); e.Result = true; } else { // Other status; return false e.Result = false; } } catch (WebException) { // Deffinitely offline e.Result = false; } } 当BackgroundWorker 对象完成了他的工作,,也就是定义DoWork 里的事件,他会触发RunWorkerCompleted 事件,这个事件也定义了一个定制的事件句柄- RunWorkerCompletedEventArgs 有了这个类,我们就可以管理ToolStripStatusLabel的显示了 ...

2012-09-24 · 2 min · bystander

一个可定制的WPF任务对话框

今天实在看WPF揭秘的时候看到TaskDialog这个控件的。然后就去找了一下开源的代码。在codeproject上发现了这个,非常给力。。另外codeproject改版后很漂亮哦。 介绍: 这是用WPF实现Vista上TaskDialog效果的代码。 Messagbox消息框 通过调用重写的静态Show方法。TaskDialog就会表现的像一个Messagebox。他有四个文本类型的属性:Header(头部), Content(内容), Detail(更多), 和 Footer(底部),其实Detail是一个折叠的区域, 而Header和Footer还有一个icon属性(HeaderIcon和FooterIcon),除此之外,Header还有Background(背景)和Foreground(前景)属性 // TaskDialog.Show方法签名 public static TaskDialogResult Show( string title, string header, string content, string detail, string footer, TaskDialogButton button, TaskDialogResult defaultResult, TaskDialogIcon headerIcon, TaskDialogIcon footerIcon, Brush headerBackground, Brush headerForeground) // TaskDialog.Show 方法的一个例子 TaskDialog.Show("Task Dialog 测试", "消息框的标题文字", "消息框的内容部分. " + " 可以自适应内容.", "消息框的细节部分 " + "可以自适应内容", "消息框的底部.", TaskDialogButton.Ok, TaskDialogResult.None, TaskDialogIcon.Information, TaskDialogIcon.Shield, Brushes.White, Brushes.Navy); 定制TaskDialog 使用静态的Show方法。Header, Content, Detail, 和Footer 就限制了只能传递字符串作为值了。 为了定义这个对话框,你先创建TaskDialog类的一个对象,然后分别设置一下各个属性,最后调用Show方法就可以了 // TaskDialog 实例化例子 TaskDialog dialog = new TaskDialog(); dialog.title: = "TaskDialog example"; dialog.HeaderIcon = TaskDialogIcon.Warning; dialog.SystemSound = TaskDialogSound.Exclamation; // header 属性设置 dialog.Header = "This is the Header."; dialog.HeaderBackground = Brushes.DarkGray; dialog.HeaderForeground = Brushes.White; // Content, Detail 和 Footer属性设置 dialog.Content = "This is the content"; dialog.Detail = "This is the detail"; dialog.Footer = "this is the Footer"; dialog.Show(); TaskDialog控件派生自HeaderedContentControl类,因为从HeaderedContentControl类可以获得Header和Content属性,TaskDialog仅仅是添加了Detail和Footer属性,这些属性是Object类型,并且有他们自己的template(模板)属性HeaderTemplate, ContentTemplate, DetailTemplate, 和 FooterTemplate),TaskDialog类对于文本内容有着缺省的数据模板,当然你也可以用那四个模板来替换,这样你就可以以你喜欢的任何方式来格式化文本了。下面这个图展示了通过斜体和下划线来格式化文本。 图2 //为上面这个图的content属性的 DataTemplate 模板 <DataTemplate x:Key="_customContentDataTemplate"> <TextBlock Text="{Binding Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:TaskDialog}}}" FontStyle="Italic" TextDecorations="Underline" TextWrapping="Wrap"/> </DataTemplate> 因为Header,Content,Detail和Footer是object类型,因此不再受到只能是文本的限制了,你可以防止你喜欢的任何类型到TaskDialog,下面这个例子中的TaskDialog是不是很像UAC的提示呢。这里Content属性是一个UserControl类型,放置了一个图片和一些文本还有两个CommandButtons(都是普通的按钮。。不过添加了一些定制的样式,再加了Header属性) ...

2012-09-24 · 1 min · bystander

C++ 独立引用,为什么?

问题: I read in some good C++ tutorial that independent references do exist, and act like aliasing. 我读了一些好的C++文章,发现独立引用确实存在,并且很像别名。 But… I wonder what it is made for. 但是,,,我想知道他适用于什么情况。 Why should one want to use aliasing.Besides, some piece of code that is not clear to me: 为什么有人想使用别名呢,另外,下面这段代码我不太清楚。 int a; int &ref = a; // independent reference int b = 19; ref = b; cout << a << " " << ref << "\n"; ref--; cout << a << " " << ref << "\n"; First, ref is a ‘reference’ to a.I understand from second line of code that address for ref (hence the ampershead) is 首先,ref是一个对a的引用,从第二行代码那我认为ref的地址也就是a,(括号里面不清楚什么意思。貌似是作者写错了) a. Then, integer ref is assigned the value of b (19). First cout returns a and ref, both equal to 19. 然后呢,整数ref被b(19)被赋值,第一次输出a和ref,都是19, Why? Isn’t integer a the address for ref? Then, decrements ref, and last cout gives two times 18. a and ref where decremented. 为什么,难道整数a不是给ref的地址?然后ref自减,最后输出了2个18,a和ref都减少了。 ...

2012-05-23 · 2 min · bystander

c & c++中sizeof返回值不同?

问题: A character array is defined globally and a structure with same name is defined within a function. 一个字符数组被定义为全局变量,一个相同名字的结构体被定义在一个函数内部。 Why sizeof operator returns different values for c & c++ ? 为什么sizeof操作符对于C和C++返回了不同的值呢? char S[13]; void fun() { struct S { int v; }; int v1 = sizeof(S); } // returns 4 in C++ and 13 in C 答案: Because in C++, the struct you defined is named S, while in C, 因为在C++中,你定义的结构体的名称是S,而在C中, it’s named struct S (which is why you often see typedef struct used in C code). 他叫做struct S(这也是为什么我们可以经常看到typedef struct 被用在C代码中)。 In C, to refer to the struct type, you need to say struct S. Therefore, sizeof(S) refers to the array. 在C中,引用一个结构类型的时候,你必须说struct S,因此,sizeof(S)调用的是数组S。 In C++, struct is unnecessary. So the local S hides the global S. 在C++中,struct这个字不是必需的,所以局部变量S隐藏了全局变量S。 If you were to change the code to the following, you would get the expected results: 如果你把代码改成下面的样子,你就能得到你期望的结果了。 ...

2012-05-22 · 1 min · bystander

为什么sizeof(str.substr(0,3).c_str())=8?

问题: string str = "abcdefgdcb"; cout &lt; &lt; sizeof(str.substr(0,3).c_str()); For some reason, the above string is giving me 8. I assumed c_str() returns a null string, 由于某些原因,上面的这个字符串得到的结果是8,我估计c_str()返回了一个null, and sizeof uses the null to determine the size of the string. 并且sizeof函数使用这个null来定义这个字符串的大小。 答案: Because sizeof doesn’t give you the length of a string, 因为sizeof给你的不是一个字符串的长度, it gives you the size of the type (const char * in this case). Try strlen. 他给你的是这个类型的大小(这种情况下的类型是c_str()返回的const char*类型),想要得到正确的结果,试试strlen函数吧。 On your system, sizeof (const char ) == 8, like any other pointer. 在你的系统上,sizeof(const char)=8,和其他所有的指针类型一样。 8 is the size of a pointer on your machine (64-bit) 8是在你的64位电脑上一个指针的大小 There’s your problem. sizeof tells you the size of a variable, 别乱假设,sizeof告诉你一个变量的大小, which has nothing to do with the value inside the variable, ever. 他不会进入变量里面对变量做任何改变的。。永远不会。 问题:http://stackoverflow.com/q/10668764/764869

2012-05-21 · 1 min · bystander