WinFormc#试题
C# WinForm窗体及其控件的自适应
C# WinForm窗体及其控件的自适应C# WinForm窗体及其控件自适应各种屏幕分辨率一。
说明我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。
实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。
因为窗体上控件的位置和大小是相对于自己所在的窗体的,也就是所谓的窗口坐标。
在这里我们只考虑相对于自己窗体的窗口坐标更简单,也就是成比例变化。
为了多个窗体共用,我在这里创建一个类AutoSizeFormClass ,1.使用它去记录窗体和其控件的初始位置和大小,2.根据窗体变化了的大小,成比例地实现其控件的水平和垂直方向的变化,也就是自适应。
二。
使用方法使用方法很简单,1.把自适应的类整体复制到你的工程命名空间里,然后在需要自适应的窗体中做3步即可:2.声明自适应类实例。
3.为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件初始位置和大小4.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应三。
完整代码如下:(一)。
自适应窗体的代码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace WindowsApplication1{public partial class Form1 : Form{//1.声明自适应类实例AutoSizeFormClass asc = new AutoSizeFormClass();public Form1(){InitializeComponent();}//2. 为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件的初始位置和大小private void Form1_Load(object sender, EventArgs e){asc.controllInitializeSize(this);}//3.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应private void Form1_SizeChanged(object sender, EventArgs e){asc.controlAutoSize(this);}}}(二)。
C# winform 常用控件大全
1、窗体 (2)2、Label 控件 (4)3、TextBox 控件 (4)4、RichTextBox控件 (6)5、NumericUpDown 控件 (7)6、Button 控件 (8)7、GroupBox 控件 (8)8、RadioButton控件 (8)9、CheckBox 控件 (9)10、ListBox 控件 (9)11、ComboBox 控件 (11)12、CheckedListBox 控件 (11)13、PictureBox 控件的使用 (11)14、Timer 控件 (12)15、ProgressBar控件和TrackBar控件 (12)16、HScrollBar 控件和VScrollBar控件的使用 (14)17、OpenFileDialog 控件 (14)18、SaveFileDialog 控件 (15)19、FontDialog 控件 (15)20、ColorDialog控件 (15)21、PrintDialog控件和PrintDocument 控件 (16)22、用户自定义对话框 (16)23、菜单控件 (16)25、MDI 应用程序设计 (17)26、键盘事件处理 (18)27、鼠标事件处理 (19)28、排列窗体上的控件 (19)1、窗体1、常用属性(1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体。
(2)WindowState属性:用来获取或设置窗体的窗口状态。
取值有三种:Normal (窗体正常显示)、Minimized(窗体以最小化形式显示)和Maximized(窗体以最大化形式显示)。
(3)StartPosition属性:用来获取或设置运行时窗体的起始位置。
其取值及含义如表9-1 所示。
默认的起始位置是WindowsDefaultLocation。
(4)Text属性:该属性是一个字符串属性,用来设置或返回在窗口标题栏中显示的文字。
c#WinForm窗体之间传值的几种方式(小结)
c#WinForm窗体之间传值的⼏种⽅式(⼩结)前⾔⼩编最近维护⼀个Winfrom窗体,是项⽬中CS端的主窗体,很多⼦窗体需要从主窗体获取值,同时⼦窗体还需要给主窗体回传值,下⾯来给⼤家介绍⼀下。
正⽂本⽂中以主窗体为frmMain,⼦窗体为frmGroup ,两窗体之间的传值来做⽰例。
⽅式⼀:使⽤公共静态变量传值主窗体frmMain中代码public partial class frmMain : Form{//声明⼯位ID 为公共静态变量public static string terminalID = "";//给静态变量赋值terminalID = "q13bh01-bh12";}⼦窗体frmGroup中代码private void frmGroup_Load(object sender, EventArgs e){this.txtTerminalID.Text= frmMain.terminalID.Trim();//可以再赋值给静态成员,⽅便其他窗体调⽤frmMain.terminalID = "q13bh01-bh11";}特点:双向传值,实现简单缺点:静态变量在类加载的时候分配内存,存储于⽅法区,⼀般不会被销毁,在系统不够内存情况下会⾃动回收静态内存,这样就会引起访问全局静态错误。
⽅式⼆:使⽤公共变量传值主窗体frmMain中代码public partial class frmMain : Form{//声明⼯位ID 为公共变量public string terminalID = "";//给变量赋值terminalID = "q13bh01-bh12";//单击‘⾏为'按钮的时候会给窗体传值private void btnGroup_Click(object sender, EventArgs e){frmGroup frmGro = new frmGroup();//变量传值,注意顺序写在ShowDialog()⽅法之前frmGro .stationID = this.terminalID;frmGro .ShowDialog();}}⼦窗体frmGroup中代码public partial class frmGroup : Form{//定义公共属性public string stationID = "";}特点:单向传值,只能主窗体给⼦窗体传值,实现简单⽅式三:使⽤委托传值先来看⼦窗体frmGroup中代码namespace Siemens.Simatic.GUIClient.MESClient{//1、声明⼀个委托public delegate void setTextValue(string textValue,bool flag);public partial class frmGroup : Form{//2、声明⼀个委托类型的事件public event setTextValue setFormTextValue;public string groupName = "";public bool flagBtnGroup = false;public frmGroup(){InitializeComponent();}//轮询‘⾏为'按钮(相当于按钮单击事件)private void tmrBtn_Tick(object sender, EventArgs e){if (sender is ButtonX) {ButtonX butX = (ButtonX)sender;//判断触发事件的是不是ButtongroupName = butX.Text.Trim();flagBtnGroup = true;//3、准备要回传的数据。
CWinForm基础
运VS行自时动生成的代码 合到一起 组程成序一员个编窗写体的文代件码
private void InitialBiblioteka zeComponent(){
// VS自动生成的代码
// Form1.cs
this.ShowInTaskbar = false; namespace MyForm
认识WinForm
工具箱
工作区域
窗体
解决方案 项目名称 窗体名称
主程序文 件,包含 Main方法
窗体
Main()方法
// Program.cs
namespace MyForm
{
static class Program {
…….. static void Main( )
Main 方法, 程序的入口
KeyDown
在窗体有焦点的情况下按下键时发生。
KeyPress
在窗体有焦点的情况下按下键时发生。
KeyUp
在窗体有焦点的情况下释放键时发生。
Load Resize
在第一次显示窗体前发生。 在调整窗体大小时发生。
窗体
事件驱动
Windows 系统中处处是事件: – 鼠标按下、鼠标释放、键盘键按下…… Windows 系事件统触通发过事件处理来响应事用件响户应的的请结果求
常用属性
属性 AcceptButton BackColor BackgroundImage FormBorderStyle Name Size StartPosition Text WindowState
说明 获取或设置当用户按Enter键时所单击的窗体上的按钮。 获取或设置窗体的背景色。 获取或设置在窗体中显示的背景图像。 获取或设置窗体的边框样式。 获取或设置窗体的名称。 获取或设置窗体的大小。 获取或设置运行时窗体的起始位置。 获取或设置窗体的标题文本。 获取或设置窗体的窗口状态。
c#winform窗口一直置顶显示在桌面最上方或最底层的方法
c#winform窗⼝⼀直置顶显⽰在桌⾯最上⽅或最底层的⽅法⼀、在最前⾯:using System.Runtime.InteropServices;在定义部分引⼊下⾯两个函数:[DllImport( "user32 ")]private static extern IntPtr FindWindow(string lpClassName,string lpWindowName);[DllImport( "user32 ")]private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);在窗体On_Load事件中添加(Santos的代码):IntPtr hDeskTop=FindWindow( "Progman ", "Program Manager ");SetParent(this.Handle,hDeskTop);另⼀个⽅法可以修改桌⾯壁纸实现经测试,win2000--win2003 、xp下嵌⼊桌⾯,不⽀持vista和win7以上系统⼆、using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;namespace ShowInDesk{publicpartialclass Form1 : Form{IntPtr hDesktop;publicconstint GW_CHILD =5;public Form1(){InitializeComponent();this.hDesktop = GetDesktopHandle(DesktopLayer.Progman);EmbedDesktop(this, this.Handle, this.hDesktop);isMouseDown =false;}public IntPtr GetDesktopHandle(DesktopLayer layer) { //hWnd = new HandleRef();HandleRef hWnd;IntPtr hDesktop =new IntPtr();switch (layer){case DesktopLayer.Progman:hDesktop = Win32Support.FindWindow("Progman", null);//第⼀层桌⾯break;case DesktopLayer.SHELLDLL:hDesktop = Win32Support.FindWindow("Progman", null);//第⼀层桌⾯hWnd =new HandleRef(this, hDesktop);hDesktop = Win32Support.GetWindow(hWnd, GW_CHILD);//第2层桌⾯break;case DesktopLayer.FolderView:hDesktop = Win32Support.FindWindow("Progman", null);//第⼀层桌⾯hWnd =new HandleRef(this, hDesktop);hDesktop = Win32Support.GetWindow(hWnd, GW_CHILD);//第2层桌⾯hWnd =new HandleRef(this, hDesktop);hDesktop = Win32Support.GetWindow(hWnd, GW_CHILD);//第3层桌⾯break;}return hDesktop;}publicvoid EmbedDesktop(Object embeddedWindow, IntPtr childWindow, IntPtr parentWindow){Form window = (Form)embeddedWindow;HandleRef HWND_BOTTOM =new HandleRef(embeddedWindow, new IntPtr(1));constint SWP_FRAMECHANGED =0x0020;//发送窗⼝⼤⼩改变消息Win32Support.SetParent(childWindow, parentWindow);Win32Support.SetWindowPos(new HandleRef(window, childWindow), HWND_BOTTOM, 300, 300, window.Width, window.Height, SWP_FRAMECHANGED); }}}2、using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;namespace ShowInDesk{class Win32Support{[DllImport("user32.dll", CharSet = CharSet.Auto)]publicstaticextern IntPtr FindWindow(string className, string windowName);[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling =true)]publicstaticextern IntPtr GetWindow(HandleRef hWnd, int nCmd);[DllImport("user32.dll")]publicstaticextern IntPtr SetParent(IntPtr child, IntPtr parent);[DllImport("user32.dll", EntryPoint ="GetDCEx", CharSet = CharSet.Auto, ExactSpelling =true)]publicstaticextern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, int flags);[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling =true)]publicstaticexternbool SetWindowPos(HandleRef hWnd, HandleRef hWndInsertAfter, int x, int y, int cx, int cy, int flags); [DllImport("user32.dll")]publicstaticexternint ReleaseDC(IntPtr window, IntPtr handle);}}3、namespace ShowInDesk{publicenum DesktopLayer{Progman =0,SHELLDLL =1,FolderView =2}}三、⼊桌⾯窗⼝最底层,并提供详细的实现代码供参考。
第一个C#Winform实例
第⼀个C#Winform实例前⾯我们准备好了相关的库,现在开始搭建环境,本⼈⾃动化⾏业,就⽤Windorm开发吧,例⼦仅仅做引导,希望⼤家能深⼊。
VS版本VS20171:打开VS建⽴⼀个WInform 项⽬。
拉⼊两个控件,groupbox,picturebox放到左侧,右侧也拉⼊⼀个groupbox,⾥⾯放⼊两个button.⼀个⽤来选择图⽚,⼀个⽤来测试⼆值化的效果。
UI效果如下:2:本⼈系统win10,64位。
所以⽤OpencvSharp的64位库。
先在项⽬⾥添加引⽤:(net461版本);然后在类⾥添加using OpenCvSharp;最后根据个⼈项⽬平台,选择新建X64或者X86,⽤anycpu 容易出问题。
好了,经过上⾯的准备,OpencvSharp相关库所有的东西都可以调⽤了。
3:图像少不了显⽰,我们新建⼀个类,⽤来管理OpencvSharp的图⽚显⽰。
public class SharpWindows{[DllImport("user32.dll", SetLastError = true)]private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.dll", SetLastError = true)]private static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);private PictureBox pictureBox;private Control Parentform;public Window Opencvwin;public SharpWindows(PictureBox _pictureBox,string winname){pictureBox = _pictureBox;dWindow(winname);Opencvwin = new Window(winname, WindowMode.FullScreen);Cv2.SetWindowProperty(, WindowProperty.Fullscreen, 1);IntPtr Childwin = FindWindow(null, winname);SetParent(Childwin, _pictureBox.Handle);Parentform = Control.FromHandle(_pictureBox.Handle);}public void Showimg(Mat img){try{int width = Parentform.Width;int height = Parentform.Height;Cv2.ResizeWindow(, width, height);Cv2.MoveWindow(, Parentform.Left, Parentform.Top);Cv2.SetWindowProperty(, WindowProperty.Fullscreen, 1);Opencvwin.ShowImage(img);}catch(Exception ex){throw (ex);}}}4.在winform主UI⾥⾯初始化⼀个OpencvSharp的显⽰窗⼝:(同时创建⼀个Mat变量) SharpWindows Imgwindow;Mat rawimg;public OpencvSharpWindow(){InitializeComponent();Imgwindow = new SharpWindows(this.pictureBox1, "MainUIwindow");}5.两个button点击事件:private void button_Openpic_Click(object sender, EventArgs e){try{var filename= OpenfileDlg();if(filename!=null&& filename!=""){Mat img = Cv2.ImRead(filename);Imgwindow.Showimg(img);rawimg = img.Clone();img.Dispose();}}catch(Exception ex ){throw (ex);}}private static string OpenfileDlg(string Defaultpath = null){OpenFileDialog ofd = new OpenFileDialog();ofd.Title = "请选择要打开的⽂件";//多选ofd.Multiselect = true;//初始⽬录ofd.InitialDirectory = Defaultpath;//设定⽂件类型// ofd.Filter = "*.bmp | *.jpg";ofd.ShowDialog();//获得在打开⽂件对话框中选择的⽂件的路径string path = ofd.FileName;return path;}private void button_Test_Click(object sender, EventArgs e){try{if(rawimg!=null){//转灰度Mat grayimg;if (rawimg.Channels()==3){grayimg = rawimg.CvtColor(ColorConversionCodes.BGR2GRAY);}else{grayimg = rawimg.Clone();}Imgwindow.Showimg(grayimg);//bindouble dvalue = 0;double.TryParse(textBox_ThreshValue.Text, out dvalue);if(dvalue==0){dvalue = 10;}Mat binimg = grayimg.Threshold(dvalue, 255, ThresholdTypes.Binary);Imgwindow.Showimg(binimg);grayimg.Dispose();binimg.Dispose();}}catch(Exception ex){throw (ex);}}6.代码敲完。
CWinForm实践开发教程(上)
WinForms应用程序可能存在多个窗体,用于获取用户输入的 数据和向用户显示数据
1.1.2 创建 WinForms应用程序
“开始”“程序”“Microsoft Visual 2005”“Microsoft Visual 2005”
创建 WinForms应用程序
/// <summary> /// 清理所有正在使用的资源。【下面代码: Form1.Designer.cs 】 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } 释放系统资源
删除现有的所有文本
事件
KeyPress
说明
用户按一个键结束时将发生该事件
1.1.3 WinForms 中的常用控件
按钮
属性
Enabled
说明
确定是否可以启用或禁用该控件
方法
PerformClick
说明
Button 控件的 Click 事件
事件
Click
说明
单击按钮时将触发该事件
private void button2_Click(object sender, EventArgs e) { clear(); } private void button1_Click(object sender, EventArgs e) { if (textBox1.Text == string.Empty || textBox2.Text == string.Empty) { MessageBox.Show("信息禁止为空!","登录提示"); clear(); return; } if (!textBox1.Text.Equals("admin") || !textBox2.Text.Equals("admin")) { MessageBox.Show("用户名称或密码为空!", "登录提 示"); clear(); return; } else { MessageBox.Show("欢迎您登录本系统!","消息提示"); clear(); } } public void clear() { textBox1.Clear(); textBox2.Clear(); textBox2.Focus(); }
(十二)c#Winform自定义控件-分页控件-HZHControls
(⼗⼆)c#Winform⾃定义控件-分页控件-HZHControls 前提⼊⾏已经7,8年了,⼀直想做⼀套漂亮点的⾃定义控件,于是就有了本系列⽂章。
如果觉得写的还⾏,请点个 star ⽀持⼀下吧欢迎前来交流探讨:企鹅群568015492⽬录准备⼯作当⼀个列表加载数据过多时,⽐如datagridview,如果数据过多,则可能超出内存,相应慢等问题,此时需要⽤到翻页控件。
设计思路,对翻页控件定义接⼝,基类实现,如果所列的翻页控件样式或功能⽆法满⾜你的需求的话,你只需要基类翻页控件基类或者实现接⼝即可。
定义接⼝是因为后⾯的⼀些列表控件内置了翻页控件,为了达到兼容扩展,所有使⽤了接⼝定义约束。
开始⾸先需要⼀个分页事件⽤到的委托,偷懒,只写了⼀个[Serializable][ComVisible(true)]public delegate void PageControlEventHandler(object currentSource);我们先定义⼀个接⼝IPageControl1public interface IPageControl2 {3///<summary>4///数据源改变时发⽣5///</summary>6event PageControlEventHandler ShowSourceChanged;7///<summary>8///数据源9///</summary>10 List<object> DataSource { get; set; }11///<summary>12///显⽰数量13///</summary>14int PageSize { get; set; }15///<summary>16///开始下标17///</summary>18int StartIndex { get; set; }19///<summary>20///第⼀页21///</summary>22void FirstPage();23///<summary>24///前⼀页25///</summary>26void PreviousPage();27///<summary>28///下⼀页29///</summary>30void NextPage();31///<summary>32///最后⼀页33///</summary>34void EndPage();35///<summary>36///重新加载37///</summary>38void Reload();39///<summary>40///获取当前页数据41///</summary>42///<returns></returns>43 List<object> GetCurrentSource();44///<summary>45///总页数46///</summary>47int PageCount { get; set; }48///<summary>49///当前页52 }然后定义⼀个分页基类控件,添加⼀个⽤户控件,命名UCPagerControlBase,并实现接⼝IPageControl 看下属性1///<summary>2///总页数3///</summary>4public virtual int PageCount5 {6get;7set;8 }9private int m_pageIndex = 1;10///<summary>11///当前页码12///</summary>13public virtual int PageIndex14 {15get { return m_pageIndex; }16set { m_pageIndex = value; }17 }18///<summary>19///关联的数据源20///</summary>21public virtual List<object> DataSource { get; set; }22public virtual event PageControlEventHandler ShowSourceChanged;23private int m_pageSize = 1;24///<summary>25///每页显⽰数量26///</summary>27 [Description("每页显⽰数量"), Category("⾃定义")]28public virtual int PageSize29 {30get { return m_pageSize; }31set { m_pageSize = value; }32 }33private int startIndex = 0;34///<summary>35///开始的下标36///</summary>37 [Description("开始的下标"), Category("⾃定义")]38public virtual int StartIndex39 {40get { return startIndex; }41set42 {43 startIndex = value;44if (startIndex <= 0)45 startIndex = 0;46 }47 }然后定义虚函数,并做⼀些默认实现///<summary>///第⼀页///</summary>public virtual void FirstPage(){if (DataSource == null)return;startIndex = 0;var s = GetCurrentSource();if (ShowSourceChanged != null){ShowSourceChanged(s);}}///<summary>///上⼀页///</summary>public virtual void PreviousPage(){if (DataSource == null)return;if (startIndex == 0)return;startIndex -= m_pageSize;if (startIndex < 0)startIndex = 0;var s = GetCurrentSource();if (ShowSourceChanged != null){ShowSourceChanged(s);///<summary>///下⼀页///</summary>public virtual void NextPage(){if (DataSource == null)return;if (startIndex + m_pageSize >= DataSource.Count){return;}startIndex += m_pageSize;if (startIndex < 0)startIndex = 0;var s = GetCurrentSource();if (ShowSourceChanged != null){ShowSourceChanged(s);}}///<summary>///最后⼀页///</summary>public virtual void EndPage(){if (DataSource == null)return;startIndex = DataSource.Count - m_pageSize;if (startIndex < 0)startIndex = 0;var s = GetCurrentSource();if (ShowSourceChanged != null){ShowSourceChanged(s);}}///<summary>///刷新数据///</summary>public virtual void Reload(){var s = GetCurrentSource();if (ShowSourceChanged != null){ShowSourceChanged(s);}}///<summary>///获取当前页数据///</summary>///<returns></returns>public virtual List<object> GetCurrentSource(){if (DataSource == null)return null;int intShowCount = m_pageSize;if (intShowCount + startIndex > DataSource.Count)intShowCount = DataSource.Count - startIndex;object[] objs = new object[intShowCount];DataSource.CopyTo(startIndex, objs, 0, intShowCount);var lst = objs.ToList();bool blnLeft = false;bool blnRight = false;if (lst.Count > 0){if (DataSource.IndexOf(lst[0]) > 0){blnLeft = true;}else{blnLeft = false;}if (DataSource.IndexOf(lst[lst.Count - 1]) >= DataSource.Count - 1) {blnRight = false;}else{blnRight = true;}}ShowBtn(blnLeft, blnRight);return lst;}///控制按钮显⽰///</summary>///<param name="blnLeftBtn">是否显⽰上⼀页,第⼀页</param>///<param name="blnRightBtn">是否显⽰下⼀页,最后⼀页</param>protected virtual void ShowBtn(bool blnLeftBtn, bool blnRightBtn){ }如此基类就完成了,看下完整代码1// 版权所有黄正辉交流群:568015492 QQ:6231286292// ⽂件名称:UCPagerControlBase.cs3// 创建⽇期:2019-08-15 16:00:414// 功能描述:PageControl5// 项⽬地址:https:///kwwwvagaa/net_winform_custom_control6using System;7using System.Collections.Generic;8using ponentModel;9using System.Drawing;10using System.Data;11using System.Linq;12using System.Text;13using System.Windows.Forms;1415namespace HZH_Controls.Controls16 {17 [ToolboxItem(false)]18public class UCPagerControlBase : UserControl, IPageControl19 {20#region构造21///<summary>22///必需的设计器变量。
C#winform选择文件、选择文件夹、打开文件
C#winform选择⽂件、选择⽂件夹、打开⽂件C# winform选择⽂件、选择⽂件夹、打开⽂件⽂章来⾃博客园友,这⾥只是做⼀下笔记。
⼀、选择⽂件⽤OpenDialogOpenFileDialog dialog = new OpenFileDialog();dialog.Multiselect = true;//该值确定是否可以选择多个⽂件dialog.Title = "请选择⽂件夹";dialog.Filter = "所有⽂件(*.*)|*.*";if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK){string file = dialog.FileName;}Filter 属性 赋值为⼀字符串 ⽤于过滤⽂件类型;字符串说明如下:‘|’分割的两个,⼀个是注释,⼀个是真的Filter,显⽰出来的是那个注释。
如果要⼀次显⽰多中类型的⽂件,⽤分号分开。
如:Open1.Filter="图⽚⽂件(.jpg,.gif,.bmp)|.jpg;.gif;.bmp";则过滤的⽂件类型为 “|”号 右边的 .jpg;.gif;.bmp 三种类型⽂件,在OpenDialog/SaveDialog中显⽰给⽤户看的⽂件类型字符串则是 :“|”号 左边的 图⽚⽂件(.jpg,.gif,.bmp)。
再如:Open1.Filter="图像⽂件(.jpg;.jpg;.jpeg;.gif;.png)|.jpg;.jpeg;.gif;*.png";⼆、选择⽂件夹使⽤System.Windows.Forms.FolderBrowserDialogSystem.Windows.Forms.FolderBrowserDialog dialog =new System.Windows.Forms.FolderBrowserDialog();dialog.Description = "请选择Txt所在⽂件夹";if (dialog.ShowDialog()==System.Windows.Forms.DialogResult.OK ){if (string.IsNullOrEmpty(dialog.SelectedPath)){System.Windows.MessageBox.Show(this, "⽂件夹路径不能为空", "提⽰");return;}this.LoadingText = "处理中...";this.LoadingDisplay = true;Action<string> a = DaoRuData;a.BeginInvoke(dialog.SelectedPath,asyncCallback, a);}三、直接打开某路径下的⽂件或者⽂件夹System.Diagnostics.Process.Start("ExpLore", "C:\window");C# OpenFileDialog打开⽂件对话框(详解)⼀、打开⽂件对话框(OpenFileDialog)1、 OpenFileDialog控件的基本属性InitialDirectory:对话框的初始⽬录Filter: 获取或设置当前⽂件名筛选器字符串,例如,"⽂本⽂件(.txt)|.txt|所有⽂件(.)||."FilterIndex 在对话框中选择的⽂件筛选器的索引,如果选第⼀项就设为1RestoreDirectory 控制对话框在关闭之前是否恢复当前⽬录FileName:第⼀个在对话框中显⽰的⽂件或最后⼀个选取的⽂件Title 将显⽰在对话框标题栏中的字符AddExtension 是否⾃动添加默认扩展名CheckPathExists 在对话框返回之前,检查指定路径是否存在DefaultExt 默认扩展名DereferenceLinks 在从对话框返回前是否取消引⽤快捷⽅式ShowHelp 启⽤"帮助"按钮ValiDateNames 控制对话框检查⽂件名中是否不含有⽆效的字符或序列2、 OpenFileDialog控件有以下常⽤事件FileOk 当⽤户点击"打开"或"保存"按钮时要处理的事件HelpRequest 当⽤户点击"帮助"按钮时要处理的事件可以⽤以下代码来实现上⾯这个对话框:private void openFileDialogBTN_Click(object sender, System.EventArgs e){OpenFileDialog openFileDialog=new OpenFileDialog();openFileDialog.InitialDirectory="c:\\";//注意这⾥写路径时要⽤c:\\⽽不是c:\openFileDialog.Filter="⽂本⽂件|*.*|C#⽂件|*.cs|所有⽂件|*.*";openFileDialog.RestoreDirectory=true;openFileDialog.FilterIndex=1;if (openFileDialog.ShowDialog()==DialogResult.OK){fName=openFileDialog.FileName;File fileOpen=new File(fName);isFileHaveName=true;richTextBox1.Text=fileOpen.ReadFile();richTextBox1.AppendText("");}}3、 获取对话框的⽂件名openfiledialog.FileName //获取或设置⼀个包含在⽂件对话框中选定的⽂件名字符串openfiledialog.SafeFileName //获取选定对话框中的⽂件名和扩展名⼆、打开⽂件夹对话框(FolderBrowserDialog)FolderBrowserDialog dialog = new FolderBrowserDialog();dialog.Description = "请选择⽂件路径";if (dialog.ShowDialog() == DialogResult.OK){savePath = dialog.SelectedPath;textBox2.Text = savePath;}。
winform(C#)的几种弹框
winform(C#)的⼏种弹框 1.默认情况下:
//如MessageBox.Show("确定要退出吗?")只显⽰⼀个“确定”按钮。
//"确定要退出吗?"是对话框的显⽰信息,"退出系统"是对话框的标题
2.⾃定义按钮:
//消息框中需要显⽰哪些按钮,此处显⽰“确定”和“取消”
⾸先定义成员变量例:
MessageBoxButtons messButton = MessageBoxButtons.OKCancel;
DialogResult dr = MessageBox.Show("确定要退出吗?", "退出系统", messButton);
if (dr == DialogResult.OK)//如果点击“确定”按钮
{
……
}
else//如果点击“取消”按钮
{
……
}
以下为多种⾃定义按钮:
MessageBoxButtons指定若⼲常数,⽤以定义MessageBox上将显⽰哪些按钮(来⾃MSDN)MessageBoxButtons成员:
成员名称说明
AbortRetryIgnore 消息框包含“中⽌”、“重试”和“忽略”按钮。
OK 消息框包含“确定”按钮。
(默认)
OKCancel 消息框包含“确定”和“取消”按钮。
(上例所⽰)
RetryCancel 消息框包含“重试”和“取消”按钮。
YesNo 消息框包含“是”和“否”按钮。
YesNoCancel 消息框包含“是”、“否”和“取消”按钮。
c#Winform开发分屏显示应用程序
c#Winform开发分屏显⽰应⽤程序分屏显⽰即可把⼀台主机内运⾏的多个程序分别显⽰在不同的两个(或多个)屏幕上。
⽬前市⾯上主流的显卡都⽀持分屏显⽰(显⽰双屏幕),如果需要显⽰2个以上的屏幕,则应使⽤“拖机卡”类的硬件。
设置分屏显⽰的两种⽅法如下:1、⽤两个显卡连接两台显⽰器,进⼊系统后,分清楚哪⼀个是主显卡,在桌⾯空⽩处右键单击,点属性,然后在窗⼝中点“设置”选项卡,会看到有两个显⽰,分别是1(主显卡)和2(副显卡),点击那个2,在下⾯的“将windows桌⾯扩展到该监视器”打上对号,确定后,你试着把⿏标往主显⽰器右边界移动,再移动,⿏标会跑到第⼆台显⽰器上去了,这样,同样运⾏⼏个程序,分别将它们的窗⼝拖拽到两个显⽰器的区域中就可以了,这实际上是将桌⾯扩展了⼀下。
2、使⽤专门的硬件。
可以使⽤“⼀拖多”的拖机卡,只要将设备插⼊usb⼝中,将设备上引出的两个ps/2⼝分别接⿏标和键盘,主机中还是有两块显卡,然后再装上这个设备的专⽤软件,重启后,经过简单的配置,即可实现“完全”独⽴的两个系统。
所谓的分屏或多屏软件,就是把软件中的多个窗体,在主屏幕运⾏,但是把各个窗体(坐标)移动到各个扩展屏幕位置上如下图所⽰:主屏幕(MainForm)index=0扩展屏幕1 (Form1) index=1扩展屏幕2 (Form2) index=...扩展屏幕3 (Form3) index=...以下介绍最常⽤的双屏幕显⽰,也就是左右模式的屏幕显⽰的⽅法。
WinForm 的实现办法:利⽤WinForm中的类,即可⽐较⽅便地实现多窗体分别在多个屏幕上显⽰。
获取当前系统连接的屏幕数量: Screen.AllScreens.Count();获取当前屏幕的名称:string CurrentScreenName = Screen.FromControl(this).DeviceName;获取当前屏幕对象:Screen CurrentScreen = Screen.FromControl(this);获取当前⿏标所在的屏幕:Screen CurrentScreen = Screen.FromPoint(new Point(Cursor.Position.X, Cursor.Position.Y));让窗体在第2个屏幕上显⽰:this.Left = ((Screen.AllScreens[1].Bounds.Width - this.Width) / 2);this.Top = ((Screen.AllScreens[1].Bounds.Height - this.Height) / 2);把任何窗体显⽰在任何屏幕的⽅法:[csharp]1. //在窗体的OnLoad事件中调⽤该⽅法2. protected void Form1_OnLoad(...) {3. showOnMonitor(1);//index=14. }5.6. private void showOnMonitor(int showOnMonitor)7. {8. Screen[] sc;9. sc = Screen.AllScreens;10. if (showOnMonitor >= sc.Length) {11. showOnMonitor = 0;12. }13.14.15. this.StartPosition = FormStartPosition.Manual;16. this.Location = new Point(sc[showOnMonitor].Bounds.Left, sc[showOnMonitor].Bounds.Top);17. // If you intend the form to be maximized, change it to normal then maximized.18. this.WindowState = FormWindowState.Normal;19. this.WindowState = FormWindowState.Maximized;20. }对WPF窗体来说,只要简单的更改即可:⾸先要添加对 System.Windows.Forms 和 System.Drawing 的引⽤简单的参考代码如下:[csharp]1. protected override void OnStartup(StartupEventArgs e)2. {3. base.OnStartup(e);4.5. Window1 w1 = new Window1();6. Window2 w2 = new Window2();7.8.9. Screen s1 = Screen.AllScreens[0];10. Screen s2 = Screen.AllScreens[1];11.12. Rectangle r1 = s1.WorkingArea;13. Rectangle r2 = s2.WorkingArea;14.15. w1.Top = r1.Top;16. w1.Left = r1.Left;17.18. w2.Top = r2.Top;19. w2.Left = r2.Left;20.21. w1.Show();22. w2.Show();23.24. w2.Owner = w1;25.26.27. }注意:⼀定应该在窗体加载前,判断所要显⽰的屏幕是否存在,否则会报错!转⾃:。
C#WinForm只允许运行一个窗体实例
C#WinForm只允许运⾏⼀个窗体实例⼤概看了看别⼈的⽅法,都是从语法的⾓度巧妙实现的。
我要实现的⽬的是dialogForm.Show();点击按钮显⽰对话框窗体,如果窗体没有关闭,再次点击,不重复显⽰。
我⽤了个笨⽅法,就是⽤⼀个静态类,在内存中保存个数据。
记录窗体是否显⽰。
class CGlobal{static isShow=false;}在dialogForm.Show();之前判断⼀下。
if(CGlobal.isShow==false){dialogForm.Show();}窗体显⽰后Form_Load(){CGlobal.isShow==true;}⽅法不优雅,但是容易理解,哈哈。
url:参考⼀:C# 只允许运⾏⼀个程序实例using System;using System.Windows.Forms;using System.Runtime.InteropServices;//使⽤DllImport的必须。
using System.Diagnostics;//引⼊Process 类namespace命名空间{static class Program{private const int WS_SHOWNORMAL = 1;[DllImport("User32.dll")]private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);[DllImport("User32.dll")]private static extern bool SetForegroundWindow(IntPtr hWnd);///<summary>///应⽤程序的主⼊⼝点。
///</summary>[STAThread]static void Main(){Process instance = GetRunningInstance();if (instance == null){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new frm_Main());//在这启动主窗体。
CWinForm选择文件目录程序
CWinForm选择文件目录程序C# WinForm 选择文件目录程序一、界面设计在WinForm应用程序中,我们可以使用FolderBrowserDialog控件来实现用户选择目录的功能。
该控件会弹出一个标准的文件夹选择对话框,让用户选择文件夹。
1.在Visual Studio中,创建一个新的WinForm项目。
2.从工具箱拖拽一个FolderBrowserDialog控件到Form上。
3.在Form的设计视图中,双击FolderBrowserDialog控件,会自动生成一个事件处理函数。
4.在事件处理函数中,添加代码来处理用户选择的文件夹。
二、文件目录路径获取当用户选择文件夹后,可以通过FolderBrowserDialog控件的SelectedPath属性获取选择的文件夹路径。
private void btnBrowse_Click(object sender, EventArgs e){FolderBrowserDialog folderDialog = new FolderBrowserDialog();if (folderDialog.ShowDialog() == DialogResult.OK){txtPath.Text = folderDialog.SelectedPath;}}三、路径输出为了显示用户选择的文件夹路径,我们可以在WinForm中添加一个文本框控件(TextBox),并把选择的路径赋值给文本框的Text属性。
private void btnBrowse_Click(object sender, EventArgs e){FolderBrowserDialog folderDialog = new FolderBrowserDialog();if (folderDialog.ShowDialog() == DialogResult.OK){txtPath.Text = folderDialog.SelectedPath;}}四、异常处理在获取文件夹路径时,我们需要考虑一些异常情况,例如用户取消了文件夹选择对话框,或者选择的文件夹不存在等。
C# Winform程序的项目经验
1、能用简单、基础的数据类型就绝对不用复杂、高级的2、一定要每天花一定的时间去重构你的代码,多多实践你在书中看到的“设计模式”3、团队内部的沟通是至关重要的,一定需要建立一种便捷、高效的沟通渠道4遵守一定的编码规范,比如:单个函数不要超过150行等,详细请参考《C#编程规范》。
还有就是程序中的路径必须用相对路径5 、I/O的次数越少越好(没有办法,文件读写真的很慢)6 、C#的内存泄露问题,这个问题比较复杂,请参见下一个专题7、程序的编写过程中,new 对象,操作越少越好,即使您及时的Dispose了,这个创建和删除的过程也是相当消耗资源的,会使程序变慢。
1.1 因为越是简单的数据类型就越是偏底层,越是偏底层的数据类型所占用的内存就越少,效率就越高。
复杂、高级、功能强大的数据类型,一定被别人封装了什么,这其中必然损失了效率。
当一个项目作到后期时,项目会很大,许许多多的地方都丧失了一点点的效率,这一积累起来就成了致命的问题。
1.2 在一个项目的开始,你可能认为项目的进度比较重要,就没有太多的考虑到内存、性能、重构等问题,但是到一个项目的后期,其弊端就会凸显出来,在大多数情况下,弊端积累的多了,就会带来灾难性的结果。
比如,我们的ROSE项目,在刚开始时,我们定义了大量的List<>数据类型,因为这个数据类型支持泛型,可以直接Add,不会像像数组一样,在定义的时候需要指定大小。
到后来,我们的系统在打开比较大的产品的时候,其速度还是比较慢的,总是不能让我十分满意,其实我们可以更快,做的更好。
如果可以重新开始的话,我会强烈要求,把所有的List都换成数组,摒弃Dictionary累,我相信我们的系统会快很多的。
2.1 每天花一点时间去重构你的代码,看看函数的功能是不是可以更加单纯,是不是可以更加的短(最好不要超过100行),函数与函数之间,类与类之间,层与层之间的依赖性和耦合度能不能更低。
是不是可以把多处用到一个功能的地方,封装成为一个公用的函数。
C#Winform中如何绘制动画示例详解
C#Winform中如何绘制动画⽰例详解前⾔这⾥介绍⼀个.net⾃⾝携带的类ImageAnimator,这个类类似于控制动画的时间轴,使⽤ImageAnimator.CanAnimate可以判断⼀个图⽚是否为动画,调⽤ImageAnimator.Animate可以开始播放动画,即每经过⼀帧的时间触发⼀次OnFrameChanged委托,我们只要在该委托中将Image的活动帧选⾄下⼀帧再迫使界⾯重绘就可以实现动画效果了。
为了⽅便以后的使⽤,我将这些代码整合到了⼀起,形成⼀个AnimateImage类,该类提供了CanAnimate、FrameCount、CurrentFrame等属性,以及Play()、Stop()、Reset()等动画常⽤的⽅法,代码如下using System;using System.Collections.Generic;using System.Text;using System.Drawing;using System.Drawing.Imaging;namespace GifTest{/// <summary>/// 表⽰⼀类带动画功能的图像。
/// </summary>public class AnimateImage{Image image;FrameDimension frameDimension;/// <summary>/// 动画当前帧发⽣改变时触发。
/// </summary>public event EventHandler<EventArgs> OnFrameChanged;/// <summary>/// 实例化⼀个AnimateImage。
/// </summary>/// <param name="img">动画图⽚。
</param>public AnimateImage(Image img){image = img;lock (image){mCanAnimate = ImageAnimator.CanAnimate(image);if (mCanAnimate){Guid[] guid = image.FrameDimensionsList;frameDimension = new FrameDimension(guid[0]);mFrameCount = image.GetFrameCount(frameDimension);}}}bool mCanAnimate;int mFrameCount = 1, mCurrentFrame = 0;/// <summary>/// 图⽚。
C#Winform窗体实现服务端和客户端通信例子(TCP,直接Socket方式)
C#Winform窗体实现服务端和客户端通信例⼦(TCP,直接Socket⽅式)C#Winform窗体实现服务端和客户端通信例⼦(TCP, 直接Socket⽅式)进⾏了⼀些异常处理,提⽰信息的补充,还有新增获取本地IP的⽅法1、通信原理1)服务端与客户端启动服务端后,服务端通过持续监听客户端发来的请求,⼀旦监听到客户端传来的信息(请求),两端便可以互发信息了.服务端需要绑定⼀个IP,⽤于客户端在⽹络中寻找并建⽴连接(⽀持局域⽹内部客户端与服务端之间的互相通信)2)信息发送原理将⼿动输⼊字符串信息转换成机器可以识别的字节数组,然后调⽤套接字的Send()⽅法将字节数组发送出去3)信息接收原理调⽤套接字的Receive()⽅法,获取对端传来的字节数组,然后将其转换成⼈可以读懂的字符串信息2、界⾯设计1)服务端⽂本框类IP地址, name:txtIP ; 本地端⼝,name:txtPort;聊天信息,name:txtMsg;发送消息:txtSendMsg按钮类获取IP, name :btnGetLocalIP,获取本地的IP的⽅法启动服务,name:btnServerConn, ⽀持服务端与客户端通信的前提发送消息,name:btnSendMsg ,发送消息到客户端的⽅法2)客户端⽂本框类IP地址, name:txtIP ; 本地端⼝,name:txtPort;聊天信息,name:txtMsg;发送消息:txtClientSendMsg按钮类连接服务端,name:btnListenServer, 客户端连接服务端的⽅法发送消息,name:btnSendMsg ,发送消息到服务端的⽅法3、源码例⼦1)服务端代码1using System;2using System.Collections.Generic;3using ponentModel;4using System.Data;5using System.Drawing;6using System.Linq;7using ;8using .Sockets;9using System.Text;10using System.Threading;11using System.Threading.Tasks;12using System.Windows.Forms;1314namespace TcpMsgServer15 {16public partial class FrmServer : Form17 {18public FrmServer()19 {20 InitializeComponent();21//关闭对⽂本框的⾮法线程操作检查22 TextBox.CheckForIllegalCrossThreadCalls = false;23 }2425 Thread threadWatch = null; //负责监听客户端的线程26 Socket socketWatch = null; //负责监听客户端的套接字2728///<summary>29///启动服务30///</summary>31///<param name="sender"></param>32///<param name="e"></param>33private void btnServerConn_Click(object sender, EventArgs e)34 {35try36 {37//定义⼀个套接字⽤于监听客户端发来的信息包含3个参数(IP4寻址协议,流式连接,TCP协议)38 socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);39//服务端发送信息需要1个IP地址和端⼝号40 IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text.Trim()); //获取⽂本框输⼊的IP地址41//将IP地址和端⼝号绑定到⽹络节点endpoint上42 IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(this.txtPort.Text.Trim())); //获取⽂本框上输⼊的端⼝号 43//监听绑定的⽹络节点44 socketWatch.Bind(endpoint);45//将套接字的监听队列长度限制为2046 socketWatch.Listen(20);47//创建⼀个监听线程48 threadWatch = new Thread(WatchConnecting);49//将窗体线程设置为与后台同步50 threadWatch.IsBackground = true;51//启动线程52 threadWatch.Start();53//启动线程后 txtMsg⽂本框显⽰相应提⽰54 txtMsg.AppendText("开始监听客户端传来的信息!" + "\r\n");55this.btnServerConn.Enabled = false;56 }57catch (Exception ex) {58 txtMsg.AppendText("服务端启动服务失败!" + "\r\n");59this.btnServerConn.Enabled = true;60 }61 }6263//创建⼀个负责和客户端通信的套接字64 Socket socConnection = null;6566///<summary>67///监听客户端发来的请求68///</summary>69private void WatchConnecting()70 {71while (true) //持续不断监听客户端发来的请求72 {73 socConnection = socketWatch.Accept();74 txtMsg.AppendText("客户端连接成功! " + "\r\n");75//创建⼀个通信线程76 ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);77 Thread thr = new Thread(pts);78 thr.IsBackground = true;79//启动线程80 thr.Start(socConnection);81 }82 }8384///<summary>85///发送信息到客户端的⽅法86///</summary>87///<param name="sendMsg">发送的字符串信息</param>88private void ServerSendMsg(string sendMsg)89 {90try91 {92//将输⼊的字符串转换成机器可以识别的字节数组93byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);94//向客户端发送字节数组信息95 socConnection.Send(arrSendMsg);96//将发送的字符串信息附加到⽂本框txtMsg上97 txtMsg.AppendText("服务器 " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");98 }99catch (Exception ex) {100 txtMsg.AppendText("客户端已断开连接,⽆法发送信息!" + "\r\n");101 }102 }103104///<summary>105///接收客户端发来的信息106///</summary>107///<param name="socketClientPara">客户端套接字对象</param>108private void ServerRecMsg(object socketClientPara)109 {110 Socket socketServer = socketClientPara as Socket;111while (true)112 {113//创建⼀个内存缓冲区其⼤⼩为1024*1024字节即1M114byte[] arrServerRecMsg = new byte[1024 * 1024];115try116 {117//将接收到的信息存⼊到内存缓冲区,并返回其字节数组的长度118int length = socketServer.Receive(arrServerRecMsg);119//将机器接受到的字节数组转换为⼈可以读懂的字符串120string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length); 121//将发送的字符串信息附加到⽂本框txtMsg上122 txtMsg.AppendText("天涯 " + GetCurrentTime() + "\r\n" + strSRecMsg + "\r\n"); 123 }124catch (Exception ex) {125 txtMsg.AppendText("客户端已断开连接!" + "\r\n");126break;127 }128 }129 }130131///<summary>132///发送消息到客户端133///</summary>134///<param name="sender"></param>135///<param name="e"></param>136private void btnSendMsg_Click(object sender, EventArgs e)137 {138//调⽤ ServerSendMsg⽅法发送信息到客户端139 ServerSendMsg(this.txtSendMsg.Text.Trim());140this.txtSendMsg.Clear();141 }142143///<summary>144///快捷键 Enter 发送信息145///</summary>146///<param name="sender"></param>147///<param name="e"></param>148private void txtSendMsg_KeyDown(object sender, KeyEventArgs e)149 {150//如果⽤户按下了Enter键151if (e.KeyCode == Keys.Enter)152 {153//则调⽤服务器向客户端发送信息的⽅法154 ServerSendMsg(txtSendMsg.Text.Trim());155this.txtSendMsg.Clear();156 }157 }158159///<summary>160///获取当前系统时间的⽅法161///</summary>162///<returns>当前时间</returns>163private DateTime GetCurrentTime()164 {165 DateTime currentTime = new DateTime();166 currentTime = DateTime.Now;167return currentTime;168 }169170///<summary>171///获取本地IPv4地址172///</summary>173///<returns></returns>174public IPAddress GetLocalIPv4Address() {175 IPAddress localIpv4 = null;176//获取本机所有的IP地址列表177 IPAddress[] IpList = Dns.GetHostAddresses(Dns.GetHostName());178//循环遍历所有IP地址179foreach (IPAddress IP in IpList) {180//判断是否是IPv4地址181if (IP.AddressFamily == AddressFamily.InterNetwork)182 {183 localIpv4 = IP;184 }185else {186continue;187 }188 }189return localIpv4;190 }191192///<summary>193///获取本地IP事件194///</summary>195///<param name="sender"></param>196///<param name="e"></param>197private void btnGetLocalIP_Click(object sender, EventArgs e)198 {199//接收IPv4的地址200 IPAddress localIP = GetLocalIPv4Address();201//赋值给⽂本框202this.txtIP.Text = localIP.ToString();203204 }205 }206 }2072)客户端代码208209using System;210using System.Collections.Generic;211using ponentModel;212using System.Data;213using System.Drawing;214using System.Linq;215using ;216using .Sockets;217using System.Text;218using System.Threading;219using System.Threading.Tasks;220using System.Windows.Forms;221222namespace TcpMsgClient223 {224public partial class FrmClient : Form225 {226public FrmClient()227 {228 InitializeComponent();229//关闭对⽂本框的⾮法线程操作检查230 TextBox.CheckForIllegalCrossThreadCalls = false;231 }232//创建 1个客户端套接字和1个负责监听服务端请求的线程233 Socket socketClient = null;234 Thread threadClient = null;235236///<summary>237///连接服务端事件238///</summary>239///<param name="sender"></param>240///<param name="e"></param>241private void btnListenServer_Click(object sender, EventArgs e)242 {243//定义⼀个套字节监听包含3个参数(IP4寻址协议,流式连接,TCP协议)244 socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 245//需要获取⽂本框中的IP地址246 IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text.Trim());247//将获取的ip地址和端⼝号绑定到⽹络节点endpoint上248 IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(this.txtPort.Text.Trim()));249//这⾥客户端套接字连接到⽹络节点(服务端)⽤的⽅法是Connect ⽽不是Bind250try251 {252 socketClient.Connect(endpoint);253this.txtMsg.AppendText("客户端连接服务端成功!" + "\r\n");254this.btnListenServer.Enabled = false;255//创建⼀个线程⽤于监听服务端发来的消息256 threadClient = new Thread(RecMsg);257//将窗体线程设置为与后台同步258 threadClient.IsBackground = true;259//启动线程260 threadClient.Start();261 }262catch (Exception ex) {263this.txtMsg.AppendText("远程服务端断开,连接失败!" + "\r\n");264 }265 }266267///<summary>268///接收服务端发来信息的⽅法269///</summary>270private void RecMsg()271 {272while (true) //持续监听服务端发来的消息273 {274try275 {276//定义⼀个1M的内存缓冲区⽤于临时性存储接收到的信息277byte[] arrRecMsg = new byte[1024 * 1024];278//将客户端套接字接收到的数据存⼊内存缓冲区, 并获取其长度279int length = socketClient.Receive(arrRecMsg);280//将套接字获取到的字节数组转换为⼈可以看懂的字符串281string strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length);282//将发送的信息追加到聊天内容⽂本框中283 txtMsg.AppendText("服务端 " + GetCurrentTime() + "\r\n" + strRecMsg + "\r\n"); 284 }285catch (Exception ex) {286this.txtMsg.AppendText("远程服务器已中断连接!"+"\r\n");287this.btnListenServer.Enabled = true;288break;289 }290 }291 }292293///<summary>294///发送字符串信息到服务端的⽅法295///</summary>296///<param name="sendMsg">发送的字符串信息</param>297private void ClientSendMsg(string sendMsg)298 {299try {300//将输⼊的内容字符串转换为机器可以识别的字节数组301byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);302//调⽤客户端套接字发送字节数组303 socketClient.Send(arrClientSendMsg);304//将发送的信息追加到聊天内容⽂本框中305 txtMsg.AppendText("天涯 " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");306 }307catch(Exception ex){308this.txtMsg.AppendText("远程服务器已中断连接,⽆法发送消息!" + "\r\n");309 }310 }311312private void btnSendMsg_Click(object sender, EventArgs e)313 {314//调⽤ClientSendMsg⽅法将⽂本框中输⼊的信息发送给服务端315 ClientSendMsg(this.txtClientSendMsg.Text.Trim());316this.txtClientSendMsg.Clear();317 }318319private void txtClientSendMsg_KeyDown(object sender, KeyEventArgs e)320 {321//当光标位于⽂本框时如果⽤户按下了键盘上的Enter键322if (e.KeyCode == Keys.Enter)323 {324//则调⽤客户端向服务端发送信息的⽅法325 ClientSendMsg(this.txtClientSendMsg.Text.Trim());326this.txtClientSendMsg.Clear();327 }328 }329330///<summary>331///获取当前系统时间的⽅法332///</summary>333///<returns>当前时间</returns>334private DateTime GetCurrentTime()335 {336 DateTime currentTime = new DateTime();337 currentTime = DateTime.Now;338return currentTime;339 }340 }341 }4、程序演⽰1)正常情况运⾏服务端程序,输⼊本地的IP地址,不知道可以点击获取本地IP按钮,输⼊本地端⼝,点击启动服务按钮,消息框会出现开始监听客户端信息,表⽰服务端启动服务成功运⾏客户端程序,输⼊服务端的IP和端⼝,点击连接服务端按钮,当服务端的消息框出现客户端连接成功,表⽰连接服务端成功服务端启动服务成功,客户端连接服务端成功,可以两端进⾏通信发消息2)异常处理原先参考的源码未做异常处理,导致退出程序报错,提⽰未友好等当客户端异常处理服务端中断开连接,⾃动提⽰服务端中断连接,⽆法发送消息服务端异常处理客户端断开连接,⾃动提⽰客户端断开连接,⽆法发送消息Winform窗体实现服务端和客户端通信的例⼦,转载参考:/longwu/archive/2011/08/25/2153636.htmlhttps:///weixin_34216196/article/details/85876202Ps: 这个例⼦经过原作者测试,下⾯是源码下载路径:/s/1nvRrCV3。
关于C#winform怎么调用webapi来获取到json数据
关于C#winform怎么调⽤webapi来获取到json数据C/S系统也可以和B/S系统⼀样实现“前后端分离”,那这样写winform就相当于纯粹的前端页⾯了,然后再单独部署⼀个webapi项⽬,通过api调⽤数据库进⾏数据的操作,有利于维护和数据安全性的提⾼,那么winform怎么去调⽤api接⼝呢,写了⼀个demo,⼤家借鉴⼀下哈,本⼈才疏学浅,有不⾜和错误请指出:winform界⾯就不设计了,仅仅是为了测试是否调⽤到api,直接在创建的类库中写⼀个⽅法:[csharp]1. /// <summary>2. /// 调⽤api返回json3. /// </summary>4. /// <param name="url">api地址</param>5. /// <param name="jsonstr">接收参数</param>6. /// <param name="type">类型</param>7. /// <returns></returns>8. public static string HttpApi(string url, string jsonstr, string type)9. {10. Encoding encoding = Encoding.UTF8;11. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);//webrequest请求api地址12. request.Accept = "text/html,application/xhtml+xml,*/*";13. request.ContentType = "application/json";14. request.Method = type.ToUpper().ToString();//get或者post15. byte[] buffer = encoding.GetBytes(jsonstr);16. request.ContentLength = buffer.Length;17. request.GetRequestStream().Write(buffer, 0, buffer.Length);18. HttpWebResponse response = (HttpWebResponse)request.GetResponse();19. using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))20. {21. return reader.ReadToEnd();22. }23. }然后再winform界⾯的事件中调⽤该⽅法:[csharp]1. private void button3_Click(object sender, EventArgs e)2. {3. string url = "...(此处为api端⼝)/api/VisitorInfo/GetEndVisitorInfoList";4. var str = ApiHelper.HttpApi(url, "{}", "get");5. }本地运⾏后变量str接收数据格式如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl); //--需要封装的参数request.CookieContainer = new CookieContainer();CookieContainer cookie = request.CookieContainer;//如果⽤不到Cookie,删去即可//以下是发送的http头request.Referer = "";request.Accept = "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";request.Headers["Accept-Language"] = "zh-CN,zh;q=0.";request.Headers["Accept-Charset"] = "GBK,utf-8;q=0.7,*;q=0.3";erAgent = "User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1"; request.KeepAlive = true;//上⾯的http头看情况⽽定,但是下⾯俩必须加request.ContentType = "application/x-www-form-urlencoded";Encoding encoding = Encoding.UTF8;//根据⽹站的编码⾃定义request.Method ="get"; //--需要将get改为post才可⾏string postDataStr;Stream requestStream = request.GetRequestStream();if (postDatas != ""){postDataStr=postDatas;//--需要封装,形式如“arg=arg1&arg2=arg2”byte[] postData = encoding.GetBytes(postDataStr);//postDataStr即为发送的数据,request.ContentLength = postData.Length;requestStream.Write(postData, 0, postData.Length);}HttpWebResponse response = (HttpWebResponse)request.GetResponse();Stream responseStream = response.GetResponseStream();StreamReader streamReader = new StreamReader(responseStream, encoding);string retString = streamReader.ReadToEnd();streamReader.Close();responseStream.Close();return retString; 如果是以流的⽅式提交表单数据的时候不能使⽤get⽅法,必须⽤post⽅法,改为1request.Method ="post"; 就可以了。
winform 名词解释
winform 名词解释
WinForm是Windows Form的简称,是基于.NET Framework平台的客户端(PC软件)开发技术,一般使用C#编程。
WinForm具有功能强大、操作方便、使用安全等特点。
WinForm基于C#语言,可以创建Windows窗体应用程序,每个窗体都由一个窗体控件组成,窗体控件可以包含按钮、文本框、标签等控件。
通过这些控件,可以设计出各种功能的Windows应用程序。
此外,WinForm还具有可视化设计的特点,可以通过拖拽控件的方式快速构建应用程序界面,大大提高了开发效率。
同时,WinForm还支持第三方UI库或自定义控件的接入,进一步丰富了桌面应用开发的可能性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Winform课程设计及代考题
基本功能要求:完成一个WinForm应用程序,对已有的SUPER_MARKET数据库中的商品类别和商品进行管理。
采用C# + + SQLServer2005实现
功能项1:主窗体
1.1主菜单:位于窗体顶端有如下菜单项
1.1.1商品类别管理
1.1.1.1新建商品类别:完成商品类别的新建,调用窗体参见功能项2。
如果
商品类别被新建成功,刷新1.3.1中所示商品类别树。
1.1.1.2修改商品类别:完成商品类别的更新,调用窗体参见功能项2。
如果
商品类别被更新,刷新1.3.1中所示商品类别树。
1.1.1.3删除商品类别:在选择一个商品后,将该商品删除。
删除前需要提示
用户进行确认。
删除完成后,刷新1.3.1中所示商品类别树。
1.1.1.4刷新:点击该菜单项时,重新加载1.3.1中所示商品类别树。
1.1.2商品管理
1.1.
2.1新建商品:完成商品的新建,调用窗体参见功能项3。
如果商品新建
成功,刷新1.3.2中所示商品列表。
1.1.
2.2修改商品:完成商品的修改,调用窗体参见功能项3。
如果商品修改
成功,刷新1.3.2中所示商品列表。
1.1.
2.3删除商品:完成商品的删除。
删除前需要提示用户进行确认。
删除完
成后,刷新1.3.2中所示商品列表
1.1.
2.4刷新:点击该菜单项时,重新加载1.
3.2中所示商品列表。
1.1.3基础数据管理
1.1.3.1生产商:点击后显示功能项4所示的生产商列表窗体。
1.1.4系统
1.1.4.1退出:单击该菜单项时,主窗体关闭,系统退出
1.2工具栏:位于主菜单下方,提供快捷功能,包含如下工具按钮
1.2.1新建商品类别,功能同1.1.1.1
1.2.2刷新商品类别,功能同1.1.1.4
1.2.3新建商品,功能同1.1.2.1
1.2.4刷新商品列表,功能同1.1.2.4
1.3主窗体采用SplitContainer对窗体进行左右分割
1.3.1左侧使用TreeView进行填充,显示商品类别的各个层次结构
1.3.1.1当单击TreeView中各个节点时,在右侧的ListView中显示该类别及
子类别下所有的商品明细信息
1.3.2右侧使用ListView进行填充,显示商品的明细列表,包含如下列
1.3.
2.1商品编号
1.3.
2.2商品名称
1.3.
2.3商品类别编号(隐藏)
1.3.
2.4商品名称
1.3.
2.5生产商编号(隐藏)
1.3.
2.6生产商名称
1.3.
2.7库存量
1.3.
2.8库存单位
1.3.
2.9平均价格
功能项2:商品类别编辑窗体
2.1父类别:用下拉列表进行选择,下拉列表中包含所有已有的商品类别,应有一项
空值可选表示该类别无父类别
2.2类别名称:文本框,可输入商品类别名称,最大长度50,必填项
2.3确认:按钮,点击后首先进行验证,验证通过后将数据保存到数据库中,窗体的
DialogResult设置为OK,并使窗体关闭。
2.4取消:按钮,点击后窗体的DialogResult设置为Cancel,并关闭窗体。
2.5该窗体可用于商品类别的新建和修改。
在进行修改时,窗体加载时需要加载选中
的商品类别信息,对控件显示内容进行初始化;点击确认按钮后执行Update操
作。
在新建时,父类别中默认选中在1.3.1所示TreeView中选中的商品类别,点
击确认按钮后,执行insert操作。
功能项3:商品编辑窗体
3.1商品类别:用下拉列表进行选择,必选项。
下拉列表中包含所有已有的商品类别。
3.2商品名称:文本框,可输入商品名称,最大长度100,必填项
3.3生产商:下拉列表进行选择,必选项。
下拉列表中包含所有已有的商品生产商。
3.4库存量:文本框,只允许输入整数或浮点数,最大长度12,必填项
3.5库存单位:文本框,最大长度10,必填项
3.6平均价格:文本框,最大长度12,必填项,只允许输入整数或浮点数
3.7确认:按钮,点击后首先进行验证,验证通过后将数据保存到数据库中,窗体的
DialogResult设置为OK,并使窗体关闭
3.8取消:按钮,点击后窗体的DialogResult设置为Cancel,并关闭窗体。
3.9该窗体可用于商品信息的新建和修改。
在进行修改时,窗体加载时需要加载选中
的商品信息,对控件显示内容进行初始化;点击确认按钮后执行Update操作。
在新建时,商品类别中默认选中在1.3.1所示TreeView中选中的商品类别,点击
确认按钮后,执行insert操作。
功能项4:生产商列表窗体
4.1生产商列表:ListView,窗体加载时,在该列表中显示所有的生产商。
包含如下
列:
4.1.1生产商编号
4.1.2生产商名称
4.1.3生产商地址
4.1.4生产商电话
4.2新建:按钮,点击后显示功能项5所示的生产商编辑窗体,完成生产商的新建。
如果生产商新建成功,则刷新4.1所示的生产商列表。
4.3修改: 按钮,点击后显示功能项5所示的生产商编辑窗体,完成生产商的信息修
改。
如果生产商更新成功,则刷新4.1所示的生产商列表。
4.4删除:按钮,点击后将生产商列表中选中的生产商记录删除。
删除前需要提示用
户进行确认。
删除完成后刷新4.1所示的生产商列表。
4.5退出:按钮,点击后关闭生产商列表窗体
功能项5:生产商编缉窗体
5.1生产商名称:文本框,必填项,最大输入长度100
5.2生产商地址:文本框,非必填项,最大输入长度200
5.3生产商电话:文本框,非必填项,最大输入长度50
5.4确认:按钮,点击时首先进行数据验证,验证通过后将填写的生产商信息保存进
数据库,将窗体的DialogResult设置成OK,并关闭该窗体。
5.5取消:按钮,点击时将窗体的DialogResult设置成Cancel,并关闭窗体。
5.6该窗体可用于生产商信息的新建和修改。
在进行修改时,窗体加载时需要加载选
中的生产商信息,对控件显示内容进行初始化;点击确认按钮后执行Update操
作。
在新建时,点击确认按钮后,执行insert操作。
评分标准:
a.以上功能均已实现,得85分,每漏掉一个功能,酌情扣2~5分
b.布局美观,窗体细节控制到位者,酌情加5~8分。
c.程序代码规范清晰,注释到位,模块/方法/类分配合理者,酌情加3~7分
d.禁止双方复制代码,出现雷同答卷者,双方均得0分。