将所有Form、UserControl所使用的AutoScaleMode由Font修改为None、DPI或者Inherit,界面即可正常显示
Posts Tagged ‘C#/.NET’
解决C#窗体在不同操作系统下显示错乱的问题
星期四, 19 11 月, 2009C#生成Excel文件的方法
星期三, 22 4 月, 20091. 首先添加Excel的Reference到项目中
右击项目的References,选“Add Reference…”菜单,在COM组里选择“Microsoft Excel 11.0 Object Labrary”(安装的Excel版本不一样这里的版本可能会有变化,我这里是Excel 2003)
2. 新建excel文件实例代码
Microsoft.Office.Interop.Excel.Application app = null;
Microsoft.Office.Interop.Excel.Workbook workbook = null;
Microsoft.Office.Interop.Excel.Worksheet sheet = null;
object missing = System.Reflection.Missing.Value;
try
(更多…)
解决C#中ListView控件动态添加项时闪屏的问题
星期四, 26 3 月, 2009解决原理:重载ListView控件,让控件支持Double Buffer。
重载的Double Buffer类代码如下:
/// <summary>
/// This override list view support double buffer to avoid the twinkling when insert a new item dynamically
/// </summary>
public class DoubleBufferListView : ListView
{
public DoubleBufferListView()
{
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
UpdateStyles();
}
}
C#项目文件与源程序不在同一级目录时Resources的解决办法
星期五, 26 12 月, 2008在多人开发的环境,可能为了同步方便把C#的项目文件.csproj移出源程序所在目录,这样在项目中使用Resources时会遇到这些麻烦(附解决办法):
1. 项目属性里Resources和Settings页会提示“This project does contain a default resources/settings file, Click here to create one.”,也就是说项目文件找不到缺省的Resources和Settings文件。
原因:因为IDE只会在项目文件所在目录的Properties子目录查找这两个信息,由于只把项目文件移出,真正的Properties目录仍在源码位置,所以IDE会提示找不到这两组资源。
解决办法:不用去管它,仍使用源码目录下的Properties,后面提到如何使用。
C# Array数组与ArrayList之间的互转
星期三, 24 12 月, 2008直接看实例吧:
private void _btnListArray_Click(object sender, EventArgs e)
{
string[] a = new string[3];
a[0] = "fd";
a[1] = "fe";
a[2] = "4d";
ArrayList lst = new ArrayList();
lst.AddRange(a);
lst.Add("ffe");
lst.Add("rrg");
lst[0] = "aaaa";
string[] b = (string[])lst.ToArray(typeof(string));
}
执行结果:a仍然是3个元素并保持不变,lst和b都是5个元素且第一个元素是“aaaa”。
相关链接:
http://www.cnblogs.com/biandande/archive/2008/12/16/1355761.html
http://www.cnblogs.com/smallfa/archive/2008/11/23/1339296.html
C#实现XML系列化和反系列化的总结
星期二, 23 12 月, 2008常用的系列化定义(using System.Xml.Serialization;)
[XmlAttribute("name")] // 定义<Tag name="…"></Tag>
[XmlElement("label")] // 定义<label>…</label>
[XmlIgnoreAttribute()] // 跳过系列化
[XmlElement("description", IsNullable = false)] // 定义<description>…</description>,在属性值为null时不显示该元素,即可选
[XmlArray("temp_var_list", IsNullable=false)] // 定义<temp_var_list><Tag>…</Tag>…<Tag>…</Tag></temp_var_list>,即数组对象的根结点
[XmlArrayItem("temp_var_item")] // 定义<temp_var_item>…</temp_var_item>…<temp_var_item>…</temp_var_item>,即数据元素的根结点,常与XmlArray组合使用
[XmlRoot("dpd")] // 定义要结点
几个注意事项
(1)需序列化的字段必须是公共的(public)
(2)需要序列化的类都必须有一个无参的构造函数
(3)枚举变量可序列化为字符串,无需用[XmlInclude]
(4)导出非基本类型对象,都必须用[XmlInclude]事先声明。该规则递归作用到子元素
如导出ArrayList对象,若其成员是自定义的,需预包含处理:
using System.Xml.Serialization;
[XmlInclude(typeof(自定义类))]
(5)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。
也就是说:针对值类型(如结构体)该功能是实效的
若数组包含了100个空间,填充了10个类对象,则序列化后只显示10个节点
若数组包含了100个空间,填充了10个结构体对象,则序列化后会显示100个节点
(6)真正无法XML序列化的情况
某些类就是无法XML序列化的(即使使用了[XmlInclude])
IDictionary(如HashTable)
System.Drawing.Color
System.Drawing.Font
SecurityAttribute声明
父类对象赋予子类对象值的情况
对象间循环引用
(7)对于无法XML序列化的对象,可考虑
使用自定义xml序列化(实现IXmlSerializable接口)
实现IDictionary的类,可考虑①用其它集合类替代;②用类封装之,并提供Add和this函数
某些类型需要先经过转换,然后才能序列化为 XML。如XML序列化System.Drawing.Color,可先用ToArgb()将其转换为整数
过于复杂的对象用xml序列化不便的话,可考虑用二进制序列化
实例
[SerializableAttribute] // 定义本类系列化
[XmlRoot("dpd")] // 定义为XML的根结点
public class DataProcessDef
[XmlElement("is_published")] // 枚举类型可以系列化成字符串
public PublishedTypes IsPublished
[XmlElement("data_item")] // 输出<data_item>…</data_item>
public DataItem DataItem
[XmlArray("property_list")] // 组合使用,输出<property_list><property_item>…</property_item>…<property_item>…</property_item></property_list>
[XmlArrayItem("property_item", IsNullable=false)]
public PropertyItem[] PropertyList
[XmlElement("custom_item", IsNullable=false)] // 输出<custom_item>…</custom_item>…<custom_item>…</custom_item>
public CustomItem[] CustomItems
[XmlIgnoreAttribute()] // 不系列化
public String SourceName
另一种方法
namespace TestCsXml
{
[Serializable]
public class SubClass
{
public SubClass()
{
}
public SubClass(String str)
{
_temp = str;
}
[XmlElement("Temp")]
public String Temp
{
get
{
return _temp;
}
set
{
_temp = value;
}
}
private String _temp;
}
[Serializable]
[XmlRoot("Root")]
[XmlInclude(typeof(SubClass))]
public class Class1
{
public Class1()
{
}
public Class1(String test, String name)
{
_test = test;
_name = name;
}
[XmlElement("Test")]
public String Test
{
get
{
return _test;
}
set
{
_test = value;
 
; }
}
[XmlAttribute("Name")]
public String Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
[XmlElement("Mooo")]
public IList Lst
{
get
{
return _list;
}
set
{
_list = value;
}
}
[XmlElement("Subclass")]
public IList Subcls
{
get
{
return _listObj;
}
set
{
_listObj = value;
}
}
private String _test;
private String _name;
private IList _list = new List<String>();
private IList _listObj = new List<SubClass>();
}
}
使用方法
private void button5_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream(@"E:\test2.xml", FileMode.Open);
XmlSerializer sr = new XmlSerializer(typeof(DataProcessDef));
DataProcessDef dpd = (DataProcessDef)sr.Deserialize(fs);
TextWriter wt = new StreamWriter(@"E:\test21.xml");
sr = new XmlSerializer(typeof(DataProcessDef));
sr.Serialize(wt, dpd);
wt.Close();
MessageBox.Show("OK");
}
C#右击菜单动态设置问题的解决
星期二, 20 11 月, 2007对于C# TreeView中需要动态在不同结点上显示不同的菜单时,如果在MouseUp事件中判断鼠标选中的结点然后再设置TreeView.ContextMenuStrip时,必须得用Show方法才能显示出菜单,结果会引起鼠标事件不正常。解决办法是在创建TreeNode时直接设置TreeNode.ContextMenuStrip而不是在MouseUp中判断并设置TreeView.ContextMenuStrip,连MouseUp事件都可以省了。
C# PropertyGrid自定义UserControl项不可编辑实现
星期一, 10 9 月, 2007C#的PropertyGrid控件支持给属性项自定义Converter和Editor,当指定从TypeConverter派生的Converter时可以只能从下拉列表中选择,即属性值不可手工编辑,但不支持UserControl;而指定从UITypeEditor派生的Editor可以支持UserControl但又没办法限制用户直接编辑属性值。
有时我们需要实现既能从UserControl中设定值又不想让用户直接编辑,就象一些Collection一样,只显示"(Collection)"串不可编辑又可以通过下拉或弹出窗体让用户选择。经过多次实现,发现属性项同时指定自定义Converter和Editor可以解决这个问题,后面附一些实现代码。
定义属性项:
private ItemContent _itemContent = new ItemContent();
[EditorAttribute(typeof(ContentEditor), typeof(UITypeEditor)),
TypeConverterAttribute(typeof(ConentConverter)),
DescriptionAttribute("Select item content")]
public ItemContent Content
{
get { return _itemContent; }
set { _itemContent = value; }
}
定义属性内容类:
public class ItemContent
{
private string _type = "Type";
private string _content = "Content";
public string Type
{
get { return _type; }
}
public string Content
{
get { return _content; }
set { _content = value; }
}
}
定义Converter:
public class ConentConverter : ExpandableObjectConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(ItemContent))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(System.String) &&
value is ItemContent)
{
return "(Collection)";
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
定义Editor:
public class ContentEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
SelectControl ctrl = new SelectControl();
if (value is ItemContent)
{
ctrl.Selected = (value as ItemContent).Content;
}
service.DropDownControl(ctrl);
(value as ItemContent).Content = ctrl.Selected;
return value;
}
}
实现SelectControl的UserControl,提供Selected属性,做一些操作。
最后将包含有ItemContent属性的类对象赋给PropertyGrid的SelectedObject即可。
C#PropertyGrid多行编辑实现
星期四, 1 3 月, 2007如要在PropertyGrid中显示多行编辑时需要重载UITypeEditor类并修改EditorAttribute属性。
1. 重载类MultilineTextEditor
public class MultilineTextEditor : UITypeEditor
{
private static ILog _log = LogManager.GetLogger(typeof(MultilineTextEditor));
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
try
{
IWindowsFormsEditorService svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (svc != null)
{
if (value is string)
{
TextBox box = new TextBox();
box.AcceptsReturn = true;
box.Multiline = true;
box.Height = 120;
box.BorderStyle = BorderStyle.None;
box.Text = value as string;
svc.DropDownControl(box);
return box.Text;
}
}
}
catch (Exception ex)
{
if (_log.IsErrorEnabled)
{
_log.Error(“MultilineTextEditor error: ” + ex.Message);
}
return value;
}
return value;
}
}
2. 增加EditorAttribute属性
[DescriptionAttribute(“The item description.”),
EditorAttribute(typeof(MultilineTextEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string Description
{
get { return _data.Description; }
set { _data.Description = value; }
}
3. 将包含各个属性的类实例赋给PropertyGrid的SelectedObject属性,即可通过这个实现进行读写操作。
4. PropertyGrid 的部分外观特征
通过 HelpBackColor、HelpForeColor 和 HelpVisible 属性可以更改背景颜色、更改字体颜色或隐藏说明窗格。
通过 ToolbarVisible 属性可以隐藏工具栏,通过 BackColor 属性可以更改工具栏的颜色,通过 LargeButtons 属性可以显示大工具栏按钮。
使用 PropertySort 属性可以按字母顺序对属性进行排序和分类。
通过 BackColor 属性可以更改拆分器的颜色。
通过 LineColor 属性可以更改网格线和边框。
5. 部分属性的显示方式
DescriptionAttribute – 设置显示在属性下方说明帮助窗格中的属性文本。这是一种为活动属性(即具有焦点的属性)提供帮助文本的有效方法。
CategoryAttribute – 设置属性在网格中所属的类别。当您需要将属性按类别名称分组时,此特性非常有用。如果没有为属性指定类别,该属性将被分配给杂项类别。可以将此特性应用于所有属性。
BrowsableAttribute – 表示是否在网格中显示属性。此特性可用于在网格中隐藏属性。默认情况下,公共属性始终显示在网格中。
ReadOnlyAttribute – 表示属性是否为只读。此特性可用于禁止在网格中编辑属性。默认情况下,带有 get 和 set 访问函数的公共属性在网格中是可以编辑的。
DefaultValueAttribute – 表示属性的默认值。如果希望为属性提供默认值,然后确定该属性值是否与默认值相同,则可使用此特性。
DefaultPropertyAttribute – 表示类的默认属性。在网格中选择某个类时,将首先突出显示该类的默认属性。
C#程序启动欢迎窗体实现
星期一, 26 2 月, 2007当程序在启动过程中需要花一些时间去加载资源时,我们希望程序能显示一个欢迎界面,能简单介绍软件功能的同时还能告知用户该程序还在加载中,使得用户体验更友好。
实现如下:
1. 添加欢迎界面的窗体(比如SlpashForm),做以下调整:
将FormBorderStyle属性设成None,即没有窗体边框
将StartPosition属性设成CenterScreen,即总是居中
将TopMost属性设成True,即总是在顶部
将UseWaitCursor属性设成Ture,即显示等待光标,让人感觉后台还在运行
增加一个PictureBox控件,与欢迎图片大小一致,窗体的大小也设成一致
增加一个ProgressBar控件,将Style设成Marquee,将MarqueeAnimationSpeed设成50
2. 主界面的构造函数改成以下代码:
// Create thread to show splash window
Thread showSplashThread = new Thread(new ThreadStart(ShowSplash));
showSplashThread.Start();
// Time consumed here
InitializeFrame(); // 把原来构造函数中的所有代码移到该函数中
// Abort show splash thread
showSplashThread.Abort();
showSplashThread.Join(); // Wait until the thread aborted
showSplashThread = null;
3. 显示SplashForm的线程函数
///
///
private void ShowSplash()
{
SplashForm sForm = null;
try
{
sForm = new SplashForm();
sForm.ShowDialog();
}
catch (ThreadAbortException e)
{
// Thread was aborted normally
if (_log.IsDebugEnabled)
{
_log.Debug(“Splash window was aborted normally: ” + e.Message);
}
}
finally
{
sForm = null;
}
}
4. 在主窗体的Load事件加激活自己的代码
SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle);
在使用SetForegroundWindow之前先声明一下
// Uses to active the exist window
[DllImport(“User32.dll”)]
public static extern void SetForegroundWindow(IntPtr hwnd);
实例图: