最近,我给一家公司做了个电梯多媒体软件,该软件使用C#编写,现在我将其中遇到的问题及其解决方法总结一下,以便下次再遇到同样的问题可以快速解决;同时,也给博友分享一下,共同学习,共同提高。

1、Question:关闭窗体时出现“执行CreateHandle()时无法调用值Dispose()”的错误,如下图所示:

      

Answer:原因是当前窗体的句柄还未创建完成,还存在CreateHandle()事件,还不能回收垃圾,还不能直接关闭窗体。

  在执行窗体的Close方法时,加入判断语句,如下:

if ( !IsHandleCreated)
{
this.Close();
}

2、Question:C#窗体间相互调用及数据传递方法

   Answer:当我们在一个主窗体MainForm中生成一个窗体Form1,而又需要将窗体Form1中的数据传给MainForm,此时就涉及到窗体间的相互调用。

    1)当我们在主窗体MainForm中生成窗体Form1时,采用模式窗体,将MainForm设为Form1的父窗体,在Form1中调用MainForm时直接获取其父窗体即可:

//MainForm中
Form1 form1 = new Form1();
form1.ShowDialog(this); //Form1中
MainForm mainform = (MainForm)this.Owner;
mainform.BackColor = Color.Black;
mainform.button1.BackColor = Color.Blue;

    2)使用回调对象的方法:

//MainForm中
Form1 form1 = new Form1();
form1.mainform = this;
form1.Show(); //Form1中
public MainForm mainform = new MainForm();
mainform.BackColor = Color.Black;
mainform.button1.BackColor = Color.Blue;

3、Question:局域网内文件的传输

   Answer:下面列举几种我尝试的局域网内文件传输的方法:

    1)文件复制至共享文件夹:引用Microsoft.VisualBasic.dll,调用FileSystem类的FileCopy方法

    2)FTP协议

4、Question:C/S模式中的网络通信(进程间通信)

   Answer:Socket

  

5、Question:播放视频

   Answer:COM组件Windows Media Player

  在C# .NET Windows应用程序中做视频播放,首先要用到COM组件中的WMP控件(Windows Media Player)。下面主要讲述在VS2010中WinForm窗体WMP控件的使用。

(1)在建好WinForm窗体后首先应添加COM组件Windows Media Player的引用。

(2)添加引用后,会建立其对象

private AxWMPLib.AxWindowsMediaPlayer axWindowsMediaPlayer;

  其初始化代码如下所示:

//
// axWindowsMediaPlayer
//
this.axWindowsMediaPlayer.Enabled = true;
this.axWindowsMediaPlayer.Location = new System.Drawing.Point(0, 0);
this.axWindowsMediaPlayer.Name = "axWindowsMediaPlayer";
this.axWindowsMediaPlayer.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWindowsMediaPlayer.OcxState")));
this.axWindowsMediaPlayer.Size = new System.Drawing.Size(400, 300);
this.axWindowsMediaPlayer.TabIndex = 0;

(3)设置其循环播放模式

this.axWindowsMediaPlayer.settings.setMode("loop", true);//循环播放

(4)播放列表操作

axWindowsMediaPlayer.currentPlaylist.clear();//清空
axWindowsMediaPlayer.currentPlaylist.appendItem(axWindowsMediaPlayer.newMedia("test.mp4"));//添加

(5)播放器控制

axWindowsMediaPlayer.Ctlcontrols.play();//播放

(6)Windows Media Player控件的详细说明:

[基本属性]

  • URL:string 可以指定媒体位置
  • enableContextMenu:Boolean 显示/不显示播放位置的右键菜单
  • fullScreen:boolean 全屏显示
  • stretchToFit:boolean 非全屏状态时是否伸展到最佳大小
  • uMode:string 播放器的模式,full:有下面的控制条; none:只有播放部份没有控制条
  • playState:integer 当前控件状态,状态变化时会触发OnStatusChange事件,其值如下所示:
Value State Description
Undefined Windows Media Player is in an undefined state.(未定义)
Stopped Playback of the current media item is stopped.(停止)
Paused Playback of the current media item is paused. When a media item is paused, resuming playback begins from the same location.(停留)
Playing The current media item is playing.(播放)
ScanForward The current media item is fast forwarding.
ScanReverse The current media item is fast rewinding.
Buffering The current media item is getting additional data from the server.(转换)
Waiting Connection is established, but the server is not sending data. Waiting for session to begin.(暂停)
MediaEnded Media item has completed playback. (播放结束)
Transitioning Preparing new media item.
Ready Ready to begin playing.(准备就绪)
Reconnecting Reconnecting to stream.(重新连接)

[controls]

  可通过WindowsMediaPlayer.controls对播放器进行控制并取得相关的一些信息:

  • controls.play; 播放
  • controls.stop; 停止
  • controls.pause; 暂停
  • controls.currentPosition:Double 当前播放进度
  • controls.currentPositionString:string 时间格式的字符串 “0:32″

[currentMedia]
  可以通过WindowsMediaPlayer.currentMedia取得当前媒体的信息

  • currentMedia.duration Double 总长度
  • currentMedia.durationString 时间格式的字符串 “4:34″

[settings]
  可以通过WindowsMediaPlayer.settings对播放器进行设置,包括音量和声道等。

  • settings.volume:integer 音量 (0-100)
  • settings.balance:integer 声道,通过它应该可以进行立体声、左声道、右声道的控制。

6、Question:获取并显示天气信息

   Answer:添加Web服务引用(http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx)

(1)建好WinForm项目后,添加服务引用

  

(2)获取天气的核心代码:

private string[] MyGetWeather()
{
weatherInfos = new string[]{""};//length: 32 string
try
{
MyWeatherWS.WeatherWS weather = new MyWeatherWS.WeatherWS();
weatherInfos = weather.getWeather(strWeatherCity, "");
return weatherInfos;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n远程网络连接失败!", "网络错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return weatherInfos;
}
}

(3)关于WeatherWS的使用,参考http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx

7、Question:INI配置文件操作

   Answer:

  1)调用系统函数GetPrivateProfileString()和WritePrivateProfileString()等

(1)导入库

[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

(2)调用函数读写ini配置文件

//读
StringBuilder strCom = new StringBuilder();
GetPrivateProfileString("串口参数", "端口", "", strCom, , "Setting.ini"); //写
WritePrivateProfileString("串口参数", "端口", "COM3", "Setting.ini");

  2)配置文件操作组件:SharpConfig

  SharpConfig 是 .NET 的 CFG/INI 配置文件操作组件。

  配置文件示例(sample.cfg):

[General]
# a comment
SomeString = Hello World!
SomeInteger = 10 # an inline comment
SomeFloat = 20.05
ABoolean = true

  C#代码示例:

Configuration config = Configuration.LoadFromFile( "sample.cfg" );
Section section = config["General"];
string someString = section["SomeString"].Value;
int someInteger = section["SomeInteger"].GetValue<int>();
float someFloat = section["SomeFloat"].GetValue<float>();

  上述SharpConfig参考http://www.oschina.net/p/sharpconfig

8、Question:获取并显示时间日期

   Answer:调用DateTime.Now对象的方法

//获取时间
DateTime.Now.ToLongTimeString().ToString(); // 16:16:16
//获取日期
DateTime.Now.ToLongDateString().ToString(); // 2015年9月5日
DateTime.Now.ToShortDateString().ToString(); // 2015-9-5
DateTime.Now.ToString("yyyy-MM-dd"); // 2015-09-05

9、Question:ToString()格式

   Answer:Int.ToString("Format"),Format如下所示:

10、Question:String方法

   Answer:如下所示

string s = "";
//(1)字符访问(下标访问s[i])
s = "ABCD";
Console.WriteLine(s[]); // 输出"A";
Console.WriteLine(s.Length); // 输出4
Console.WriteLine(); //(2)打散为字符数组(ToCharArray)
s = "ABCD";
char[] arr = s.ToCharArray(); // 把字符串打散成字符数组{'A','B','C','D'}
Console.WriteLine(arr[]); // 输出数组的第一个元素,输出"A"
Console.WriteLine();
//(3)截取子串(Substring)
s = "ABCD";
Console.WriteLine(s.Substring()); // 从第2位开始(索引从0开始)截取一直到字符串结束,输出"BCD"
Console.WriteLine(s.Substring(, )); // 从第2位开始截取2位,输出"BC"
Console.WriteLine(); //(4)匹配索引(IndexOf())
s = "ABCABCD";
Console.WriteLine(s.IndexOf('A')); // 从字符串头部开始搜索第一个匹配字符A的位置索引,输出"0"
Console.WriteLine(s.IndexOf("BCD")); // 从字符串头部开始搜索第一个匹配字符串BCD的位置,输出"4"
Console.WriteLine(s.LastIndexOf('C')); // 从字符串尾部开始搜索第一个匹配字符C的位置,输出"5"
Console.WriteLine(s.LastIndexOf("AB")); // 从字符串尾部开始搜索第一个匹配字符串BCD的位置,输出"3"
Console.WriteLine(s.IndexOf('E')); // 从字符串头部开始搜索第一个匹配字符串E的位置,没有匹配输出"-1";
Console.WriteLine(s.Contains("ABCD")); // 判断字符串中是否存在另一个字符串"ABCD",输出true
Console.WriteLine(); //(5)大小写转换(ToUpper和ToLower)
s = "aBcD";
Console.WriteLine(s.ToLower()); // 转化为小写,输出"abcd"
Console.WriteLine(s.ToUpper()); // 转化为大写,输出"ABCD"
Console.WriteLine(); //(6)填充对齐(PadLeft和PadRight)
s = "ABCD";
Console.WriteLine(s.PadLeft(, '_')); // 使用'_'填充字符串左部,使它扩充到6位总长度,输出"__ABCD"
Console.WriteLine(s.PadRight(, '_')); // 使用'_'填充字符串右部,使它扩充到6位总长度,输出"ABCD__"
Console.WriteLine(); //(7)截头去尾(Trim)
s = "__AB__CD__";
Console.WriteLine(s.Trim('_')); // 移除字符串中头部和尾部的'_'字符,输出"AB__CD"
Console.WriteLine(s.TrimStart('_')); // 移除字符串中头部的'_'字符,输出"AB__CD__"
Console.WriteLine(s.TrimEnd('_')); // 移除字符串中尾部的'_'字符,输出"__AB__CD"
Console.WriteLine(); //(8)插入和删除(Insert和Remove)
s = "ADEF";
Console.WriteLine(s.Insert(, "BC")); // 在字符串的第2位处插入字符串"BC",输出"ABCDEF"
Console.WriteLine(s);
Console.WriteLine(s.Remove()); // 从字符串的第2位开始到最后的字符都删除,输出"A"
Console.WriteLine(s);
Console.WriteLine(s.Remove(, )); // 从字符串的第1位开始删除2个字符,输出"EF"
Console.WriteLine(); //(9)替换字符(串)(Replace)
s = "A_B_C_D";
Console.WriteLine(s.Replace('_', '-')); // 把字符串中的'_'字符替换为'-',输出"A-B-C-D"
Console.WriteLine(s.Replace("_", "")); // 把字符串中的"_"替换为空字符串,输出"A B C D"
Console.WriteLine(); //(10)分割为字符串数组(Split)——互逆操作:联合一个字符串静态方法Join(seperator,arr[])
s = "AA,BB,CC,DD";
string[] arr1 = s.Split(','); // 以','字符对字符串进行分割,返回字符串数组
Console.WriteLine(arr1[]); // 输出"AA"
Console.WriteLine(arr1[]); // 输出"BB"
Console.WriteLine(arr1[]); // 输出"CC"
Console.WriteLine(arr1[]); // 输出"DD"
Console.WriteLine(); s = "AA--BB--CC--DD";
string[] arr2 = s.Replace("--", "-").Split('-'); // 以字符串进行分割的技巧:先把字符串"--"替换为单个字符"-",然后以'-'字符对字符串进行分割,返回字符串数组
Console.WriteLine(arr2[]); // 输出"AA"
Console.WriteLine(arr2[]); // 输出"BB"
Console.WriteLine(arr2[]); // 输出"CC"
Console.WriteLine(arr2[]); // 输出"DD"
Console.WriteLine(); //(11)格式化(静态方法Format)
Console.WriteLine(string.Format("{0} + {1} = {2}", , , + ));
Console.WriteLine(string.Format("{0} / {1} = {2:0.000}", , , 1.00 / 3.00));
Console.WriteLine(string.Format("{0:yyyy年MM月dd日}", DateTime.Now)); //(12)连接成一个字符串(静态方法Concat、静态方法Join和实例方法StringBuilder.Append)
s = "A,B,C,D";
string[] arr3 = s.Split(','); // arr = {"A","B","C","D"} Console.WriteLine(string.Concat(arr3)); // 将一个字符串数组连接成一个字符串,输出"ABCD" Console.WriteLine(string.Join(",", arr3)); // 以","作为分割符号将一个字符串数组连接成一个字符串,输出"A,B,C,D" StringBuilder sb = new StringBuilder(); // 声明一个字符串构造器实例
sb.Append("A"); // 使用字符串构造器连接字符串能获得更高的性能
sb.Append('B');
Console.WriteLine(sb.ToString());// 输出"AB"

String方法详解

11、Question:窗体控件较多时,重绘控件易引起窗体闪烁,重绘效率降低

     Answer:通过使用控件的SuspendLayout()方法,可以将控件的布局暂时挂起,其后的代码中将会把子控件的Layout事件暂时挂起,只是把相应属性的值设置为新值,并不激发Layout事件,待调用ResumeLayout()方法后,再一起使子控件的Layout事件生效。当需要立即执行布局事件时,可以直接调用PerformLayout()方法。

  在设置子控件的一些与外观、布局有关的属性时,比如Size、Location、Anchor或Dock等,会激发子控件的Control.Layout事件,并可能会引起窗口重绘。当子控件较多时,如果频繁设置上述属性(例如在窗体的初始化代码中),多个子控件的Layout事件会引起窗口重绘效率问题,比如闪烁。特别地,通过动态加载插件生成的UI对象特别多时,闪烁的情况就特别严重。此时,我们就要考虑上述解决办法。

12、Question:加密狗(SoftDog)的使用

   Answer:程序启动时先判断加密狗的序列号,决定是否启动程序;启动后再通过定时器定期检查加密狗的序列号,若发现错误及时退出程序。

13、Question:串口编程

   Answer:SerialPort组件

14、Question:多线程中,跨线程访问控件出错

   Answer:将访问控件的代码封装成一个方法,再通过Invoke()调用其委托delegate。

15、Question:窗体全屏

   Answer:代码如下所示:

private void fullScreen()
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
//this.WindowState = FormWindowState.Maximized; //屏幕分辨率
int nScreenWidth = Screen.PrimaryScreen.Bounds.Width;
int nScreenHeight = Screen.PrimaryScreen.Bounds.Height; int nWidthBorder = (this.Width - this.ClientRectangle.Width) / ;
int nHeightTitle = this.Height - this.ClientRectangle.Height - nWidthBorder; this.Left = -nWidthBorder;
this.Top = -nHeightTitle;
this.Width = nScreenWidth + nWidthBorder * ;
this.Height = nScreenHeight + nHeightTitle + nWidthBorder;
}

16、Question:焦点在其他控件上时,窗体接收不到按键消息

   Answer:设置this.KeyPreview = true;(该值指示在将键事件传递到具有焦点的控件前,窗体是否将接收此键事件)

电梯多媒体相关链接:

  ELCD_XXXM电梯多媒体显示器:http://www.embedtools.com/ADPlayer/

电梯多媒体WinForm项目Q&A总结的更多相关文章

  1. NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中

    以下是NPOI导入导出EXCEL通用类,是在别人的代码上进行优化的,兼容xls与xlsx文件格式,供参考,可直接使用在WinForm项目中,由于XSSFWorkbook类型的Write方法限制,Wri ...

  2. 循序渐进开发WinForm项目(6)--开发使用混合式Winform模块

    1.Winform数据访问模式定义 传统的Winform程序模块:用于传统的数据库通讯获取数据,这种方式获取数据,方便快捷,可以用于常规的业务系统的场景,用于单机版软件或者基于局域网内的业务系统软件. ...

  3. 循序渐进开发WinForm项目(5)--Excel数据的导入导出操作

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  4. 循序渐进开发WinForm项目(4)--Winform界面模块的集成使用

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  5. 循序渐进开发WinForm项目(3)--Winform界面层的项目设计

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  6. 循序渐进开发WinForm项目(2)--项目代码的分析

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  7. 循序渐进开发WinForm项目(1) --数据库设计和项目框架的生成

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  8. Winform项目调用asp.net数据接口

    最近一个WPF项目需要改写成android项目,思路是在asp.net项目中编写一个通用接口,便于其它平台下调用数据.刚接触到这些东西的时候完全是一头雾水,最根本的原因是不明白网站中的一个网页,为什么 ...

  9. 在类库或winform项目中打开另一个winform项目的窗体

    假设类库或winform项目为A,另一个winform项目为B.那麽在A中添加一个接口,里面有一个Show方法,然后在B中写一个类b继承这个接口,并重写这个方法,具体内容为弹出某个窗体.然后在A中另一 ...

随机推荐

  1. linux 下 文件权限和文件主

    文件与文件夹的权限和所有者 1.chmod -R 755 file 777 含义与来源: 777含义:分别为:所有者.同组用户.其他用户 7的来源:文件有三种操作模式:读4.写2.执行1,分别值为42 ...

  2. Non-ASCII characters are not allowed outside of literals and identifiers

    出现这种问题,一般是在代码里面非注释的地方,出现了非ascii字符. 比较常见的情况是,在代码中出现了中文字符.比如在引用字符串时,用了中文的引号.或者在一行代码结尾处,使用了中文的分号. 这种问题在 ...

  3. python模块介绍- SocketServer 网络服务框架

    来源:https://my.oschina.net/u/1433482/blog/190612 摘要: SocketServer简化了网络服务器的编写.它有4个类:TCPServer,UDPServe ...

  4. mysql关于or的索引问题

    摘自: http://www.educity.cn/wenda/590849.html http://blog.csdn.net/hguisu/article/details/7106159 问: 不 ...

  5. JavaScript中Math--random()/floor()/round()/ceil()

    Math.random():返回0-1之间的任意数,不包括0和1: Math.floor(num):返回小于等于num的整数,相当于四舍五入的四舍,不五入:例子:Math.floor(1.0);Mat ...

  6. COSBench性能测试配置--一张图说明一切

    COSBench性能测试配置--一张图说明一切: 测试配置,并发数,运行时间设置  

  7. 2016年11月26号随笔(关于oracle数据库)

    今天写了几个小时的sql语句,一开始我并没有思路,有思路便开始写. 首先我查询了入库表中的3级单位下的各个网点的入库信息,找到这些信息后,我又去入库明细表中查询入库的详细信息 找到了我要的把捆包箱的各 ...

  8. 服务器间打通ssh无密钥

    1 打通无密钥 配置HDFS,首先就得把机器之间的无密钥配置上.我们这里为了方便,把机器之间的双向无密钥都配置上. (1)产生RSA密钥信息 ssh-keygen -t rsa 一路回车,直到产生一个 ...

  9. devexpress中如何给TabPage控件的Tab定义背景色

    js: /*tab选项卡样式*/ .color .dxtc-link { background-color: #bf4e6a !important; } 后台代码: //选项卡样式 protected ...

  10. 9,SFDC 管理员篇 - 安全设置

    1, 使用Profile控制权限 (整体层面)     Setup | Manage Users | Profiles 总结下,一个用户只能有一个Profile,但是可以有多个Permission S ...