datagridcolumnstyle重写,实现插入不同控件列体验

最近谈论较多的就是datagrid,特别新手最是郁闷为何没有更好的控件,来满足自已的需求。
其实通过重写可以达到很多不同的功能体验,在这里我们仅仅讨论关于datagridcolumnstyle重写的问题
==========================================

1。重写textbox:

public class xp_textbox
inherits system.windows.forms.textbox

#region " windows "

public sub new()
mybase.new()

initializecomp

end sub

protected overloads overrides sub dispose(byval disposing as boolean)
if disposing then
if not (comp is nothing) then
components.dispose()
end if
end if
mybase.dispose(disposing)
end sub

'windows
private comp as system.componentmodel.ic

<system.diagnostics.debuggerstepthrough()> private sub initializecomp
'
'textbox
'
me.enablec = true
me.enablepaste = true
me.name = "textbox"

end sub

#end region

#region " variables "

private m_enpaste as boolean = true
private m_enc as boolean = true

#end region

#region " property "

property enablepaste() as boolean
get
return m_enpaste
end get
set(byval value as boolean)
m_enpaste = value
me.invalidate()
end set
end property

property enablec as boolean
get
return m_enc
end get
set(byval value as boolean)
m_enc = value
me.invalidate()
end set
end property

#end region

protected overrides sub wndproc(byref m as system.windows.forms.message)
select case m.msg
case &h302 'paste
raiseevent pasteevent()
if not m_enpaste then return
case &h7b 'c
if not m_enc then return
end select
mybase.wndproc(m)
end sub

public event pasteevent()

end class

2。重写datagridcolumnstyle(重点介绍内容):

imports system.drawing
imports system.windows.forms

public notinheritable class datagridtextboxcolumnstyle
inherits system.windows.forms.datagridcolumnstyle

#region "declare property"

private withevents m_textbox as new landlord.component.xp_textbox
private isediting as boolean
private editingrow as integer = -1
private m_oldvalue as string

#end region

#region " windows "

sub new()
me.m_textbox.visible = false
end sub

public sub new(byval c as system.componentmodel.ic
myclass.new()

container.add(me)
end sub

protected overloads overrides sub dispose(byval disposing as boolean)
if disposing then
if not (comp is nothing) then
components.dispose()
end if
end if
mybase.dispose(disposing)
end sub

private comp as system.componentmodel.ic

<system.diagnostics.debuggerstepthrough()> private sub initializecomp
comp = new system.componentmodel.c
end sub

#end region

#region "get functi

protected overrides function getminimumheight() as integer
return m_textbox.preferredheight + 2
end function

protected overrides function getpreferredheight(byval g as system.drawing.graphics, byval value as object) as integer
return m_textbox.preferredheight + 2
end function

protected overrides function getpreferredsize(byval g as system.drawing.graphics, byval value as object) as system.drawing.size
return new size(50, m_textbox.preferredheight + 2)
end function

#end region

#region "paint"

protected overloads overrides sub paint(byval g as system.drawing.graphics, byval bounds as system.drawing.rectangle, byval [source] as system.windows.forms.currencymanager, byval rownum as integer)
paint(g, bounds, [source], rownum, false)
end sub

protected overloads overrides sub paint(byval g as system.drawing.graphics, byval bounds as system.drawing.rectangle, byval [source] as system.windows.forms.currencymanager, byval rownum as integer, byval aligntoright as boolean)
dim brush_for as brush = new solidbrush(me.datagridtablestyle.forecolor)
dim brush_bak as brush = new solidbrush(me.datagridtablestyle.backcolor)
paint(g, bounds, [source], rownum, brush_bak, brush_for, aligntoright)
brush_for.dispose()
brush_bak.dispose()
end sub

protected overloads overrides sub paint(byval g as system.drawing.graphics, byval bounds as system.drawing.rectangle, byval [source] as system.windows.forms.currencymanager, byval rownum as integer, byval backbrush as brush, byval forebrush as brush, byval aligntoright as boolean)
dim str as string
if isdbnull(getcolumnvalueatrow([source], rownum)) then
str = me.nulltext
else
str = ctype(getcolumnvalueatrow([source], rownum), string)
end if
dim brush as brush = backbrush
dim rect as system.drawing.rectangle = bounds
g.fillrectangle(brush, rect)
if me.isediting and editingrow = rownum then
brush = new solidbrush(color.white)
g.fillrectangle(brush, bounds)
end if
rect.offset(0, 2)
rect.height -= 2
brush = new solidbrush(me.datagridtablestyle.forecolor)
if me.datagridtablestyle.datagrid.isselected(rownum) then
brush = new solidbrush(me.datagridtablestyle.selecti
dim rectf as rectanglef = new rectanglef(bounds.x, bounds.y, bounds.width, bounds.height)
g.fillrectangle(brush, rectf)
brush = new solidbrush(me.datagridtablestyle.selecti
end if
if me.alignment = horizontalalignment.center then
dim w as integer = g.measurestring(str, me.datagridtablestyle.datagrid.f new sizef(bounds.width, bounds.height)).width
rect.x = rect.x + (bounds.width – w) / 2
elseif me.alignment = horizontalalignment.right then
dim w as integer = g.measurestring(str, me.datagridtablestyle.datagrid.f new sizef(bounds.width, bounds.height)).width
rect.x = bounds.right – w
end if
g.drawstring(str, me.datagridtablestyle.datagrid.f brush, rect.x, rect.y)
brush.dispose()
end sub

#end region

#region "overrides method"

protected overrides function commit(byval datasource as system.windows.forms.currencymanager, byval rownum as integer) as boolean
me.m_textbox.bounds = rectangle.empty
if not me.isediting then
return true
end if
editingrow = -1
isediting = false
try
dim value as object
value = m_textbox.text
if nulltext.equals(value) then
value = system.dbnull.value
end if
setcolumnvalueatrow(datasource, rownum, value)
catch ex as exception
abort(rownum)
return false
end try
invalidate()
return true
end function

protected overrides sub abort(byval rownum as integer)
me.m_textbox.text = m_oldvalue

editingrow = -1

if m_textbox.focused then
me.datagridtablestyle.datagrid.focus()
end if
me.m_textbox.visible = false

me.isediting = false
me.invalidate()
end sub

protected overloads overrides sub edit(byval source as system.windows.forms.currencymanager, byval rownum as integer, byval bounds as system.drawing.rectangle, byval [readonly] as boolean, byval instanttext as string, byval cellisvisible as boolean)
editingrow = rownum
isediting = true
dim value as string
if isdbnull(getcolumnvalueatrow(source, rownum)) then
value = me.nulltext
else
value = ctype(getcolumnvalueatrow(source, rownum), string)
end if
m_oldvalue = value
if cellisvisible then
if not me.readonly then
me.m_textbox.bounds = new rectangle(bounds.x + 1, bounds.y + 1, bounds.width – 2, bounds.height – 2)
me.m_textbox.text = value
me.m_textbox.select()
me.m_textbox.focus()
me.m_textbox.selectall()
me.m_textbox.visible = true
me.m_textbox.flat = true
end if
else
me.m_textbox.text = value
'滚动时会丢失焦点
'me.m_textbox.visible = false
end if
if me.m_textbox.visible then
datagridtablestyle.datagrid.invalidate(bounds)
end if
end sub

protected overloads overrides sub setdatagridincolumn(byval value as system.windows.forms.datagrid)
mybase.setdatagridincolumn(value)
if not m_textbox.parent is nothing then
m_textbox.parent.controls.remove(me.m_textbox)
end if
if not value is nothing then
value.controls.add(me.m_textbox)
end if
end sub

protected overrides sub c
editingrow = -1
'否则先点到新增行,再回选非新行格时该列最后一行的值变为(null)
isediting = false
me.m_textbox.visible = false
invalidate()
end sub

protected overrides sub enternullvalue()
me.m_textbox.text = me.nulltext
end sub

private sub m_textbox_keypress(byval sender as object, byval e as system.windows.forms.keypresseventargs) handles m_textbox.keypress
if not char.iscontrol(e.keychar) then
me.isediting = true
mybase.columnstartedediting(m_textbox)
end if
end sub

private sub m_textbox_pasteevent() handles m_textbox.pasteevent
me.isediting = true
me.columnstartedediting(m_textbox)
end sub

#end region

end class

3。使用:
新建一个空窗体,拖入datagrid,窗体load事件中代码如下
private idtb_temp as new datatable

private sub form1_load(byval sender as system.object, byval e as system.eventargs) handles mybase.load

idtb_temp = new datatable("nametable")
idtb_temp.columns.add(new datacolumn("normal"))
idtb_temp.columns.add(new datacolumn("textbox1"))
idtb_temp.columns.add(new datacolumn("combobox1"))
dim datecolumns as datacolumn
datecolumns = new datacolumn("datetime1", type.gettype("system.datetime"))
idtb_temp.columns.add(datecolumns)
idtb_temp.columns.add(new datacolumn("checkbox1", type.gettype("system.boolean")))

dim idrw_row as datarow
dim i as integer
for i = 0 to 20
idrw_row = idtb_temp.newrow
idrw_row.item("normal") = "names"
idrw_row.item("textbox1") = "nick"
idrw_row.item("combobox1") = i.tostring
idrw_row.item("datetime1") = "2004-06-04"
idrw_row.item("checkbox1") = true
idtb_temp.rows.add(idrw_row)
next

me.datagrid1.datasource = idtb_temp

dim mygridstyle as windows.forms.datagridtablestyle = new windows.forms.datagridtablestyle
mygridstyle.mappingname = "nametable"
mygridstyle.preferredrowheight = 30
mygridstyle.selecti = color.blue
mygridstyle.backcolor = color.yellow

dim c1 as windows.forms.datagridtextboxcolumn = new windows.forms.datagridtextboxcolumn
with c1
.mappingname = "normal"
.width = 100
.headertext = "normal"
.alignment = horizontalalignment.center
end with
mygridstyle.gridcolumnstyles.add(c1)

dim c2 as landlord.component.draggrid.datagridtextboxcolumnstyle = new landlord.component.draggrid.datagridtextboxcolumnstyle
with c2
.mappingname = "textbox1"
.width = 100
.headertext = "textbox1"
end with
mygridstyle.gridcolumnstyles.add(c2)

dim c3 as landlord.component.draggrid.datagridcomboboxcolumnstyle = new landlord.component.draggrid.datagridcomboboxcolumnstyle
with c3
.mappingname = "combobox1"
.headertext = "combobox1"
.width = 100
.additem("111")
.additem("222")
.alignment = horizontalalignment.center
end with
mygridstyle.gridcolumnstyles.add(c3)

dim c4 as landlord.component.draggrid.datagriddatetimepickercolumnstyle = new landlord.component.draggrid.datagriddatetimepickercolumnstyle
with c4
.mappingname = "datetime1"
.headertext = "datetime1"
.width = "100"
.alignment = horizontalalignment.center
end with
mygridstyle.gridcolumnstyles.add(c4)

dim c5 as landlord.component.draggrid.datagridcheckboxcolumnstyle = new landlord.component.draggrid.datagridcheckboxcolumnstyle
with c5
.mappingname = "checkbox1"
.headertext = "checkbox1"
.width = 100
.truecolor = color.red
end with
mygridstyle.gridcolumnstyles.add(c5)

me.datagrid1.tablestyles.clear()
me.datagrid1.tablestyles.add(mygridstyle)

end sub

4。说明:
其他控件的加入原理基本一样,这里就不重复了

switch语句的“不准遍历”

switch语句的“不准遍历”
switch语句的“不准遍历”
来源:网络收集 加入时间:10月28日 09:22
c和c++语言允许switch语句中case标签后不出现break语句从而可以继续执行下面case后的语句。但是这往往由于程序员忘记写break语句而成为一个难以发现的漏洞,所以c#不允许这样,它要求每个标签项后使用break语句或跳转语句goto,即不允许从一个case自动遍历到其他case,否则编译时报错,即使是default语句后也不例外。

这个特定决定了三个特点:

a)我们可以任意排列switch语句中的case项而不会影响switch语句的功能。

b)如果要像c/c++那样在执行完后继续遍历其他的语句,只要在case语句后加上以下两条跳转语句中的一条即可:goto case label;goto default。

3)除了goto外,throw和return也可以。

c#switch语句与c/c++另一个不同点是c#同vb一样把字符串常量当作常量表达式来使用,但c/c++却不支持。所以在c#中,case “ok”:这样的形式也是支持的。

C#中的代理(delegate)

c#中的代理(delegate)
有些书上也称“代表”或“委托”。 c#中取消了指针的概念。对指针恋恋不舍的程序员可以有两种解决方法:声明“非安全”(unsafe)代码段然后在其中使用指针或者使用c#的一个引用类型——“代理”(delegate)。“代理”相当与c中的函数指针原型,区别是c#是类型安全的。
“代理”(delegate)(代表、委托):“代理”是类型安全的并且完全面向对象的。
(1)在c#中,所有的代理都是从system.delegate类派生的(delegate是system.delegate的别名)。
(2)代理隐含具有sealed属性,即不能用来派生新的类型。
(3)代理最大的作用就是为类的事件绑定事件处理程序。
(4)在通过代理调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。(5)在代理实例中可以封装静态的方法也可以封装实例方法。
(6)在创建代理实例时,需要传递将要映射的方法或其他代理实例以指明代理将要封装的函数原型(.net中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。
(7)只有当两个代理实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。
(8)多个代理实例可以形成一个代理链,system.delegate中定义了用来维护代理链的静态方法combi
(9)代理的定义必须放在任何类的外面,如delegate int mydelegate();而在类的方法中调用mydelegate d = new mydelegate(myclass.mymethod);来实例化自定义代理的实例。
(10)代理三步曲:
a.生成自定义代理类:delegate int mydelegate();
b.然后实例化代理类:mydelegate d = new mydelegate(myclass.mymethod);
c.最后通过实例对象调用方法:int ret = d();

C#中的“装箱”(boxing)与“拆箱”(unboxing)

c#中的“装箱”(boxing)与“拆箱”(unboxing)
装箱和拆箱:任何值类型、引用类型可以和object(对象)类型之间进行转换。装箱转换是指将一个值类型隐式或显式地转换成一个object类型,或者把这个值类型转换成一个被该值类型应用的接口类型(interface-type)。把一个值类型的值装箱,就是创建一个object实例并将这个值复制给这个object,装箱后的object对象中的数据位于堆中,堆中的地址在栈中。被装箱的类型的值是作为一个拷贝赋给对象的。如:

int i = 10;

object obj = i; //隐式装箱

object obj = object(i); //显式装箱

if(obj is int) //int

console.writeline(“ok”);

console.writeline(obj.gettype()); //system.int32

有两种方式来查看包装以后的引用对象中包装的原始数据的类型。要判断原始类型是否是某个给定的原子类型,用is;如果要返回一个字符串,可以用object类的gettype方法。

拆箱转换是指将一个对象类型显式地转换成一个值类型,或是将一个接口类型显式地转换成一个执行该接口地值类型。注意装箱操作可以隐式进行但拆箱操作必须是显式的。拆箱过程分成两步:首先,检查这个对象实例,看它是否为给定的值类型的装箱值。然后,把这个实例的值拷贝给值类型的变量。比如:

int i = 10;

object obj = i;

int j = (int)obj;

有两种方式来查看包装以后的引用对象中包装的原始数据的类型。要判断原始类型是否是某个给定的原子类型,用is;如果要返回一个字符串,可以用object类的gettype方法。

拆箱转换是指将一个对象类型显式地转换成一个值类型,或是将一个接口类型显式地转换成一个执行该接口地值类型。注意装箱操作可以隐式进行但拆箱操作必须是显式的。拆箱过程分成两步:首先,检查这个对象实例,看它是否为给定的值类型的装箱值。然后,把这个实例的值拷贝给值类型的变量。比如:

int i = 10;

object obj = i;

int j = (int)obj;

在C#中利用DirectX实现声音播放

在c#中利用directx实现声音播放
我感觉声音的播放比较简单。我们从播放声音开始。为什么我这么觉得?我也不知道。 这里是展示最简单的directx播放声音的例子,我尽量省略了无关的代码。最后的代码只有19行,够简单了吧?

  准备工作:

  1.安装了directx sdk(有9个dll文件)。这里我们只用到microsoft.directx.dll 和 microsoft.directx.directsound.dll

  2.一个wav文件。(这样的文件比较好找,在qq的目录里就不少啊。这里就不多说了。)名字叫snd.wav,放在最后目标程序的同个目录下面

  开始写程序啦。随便用个ultraedit就好了。

  1.引入directx 的dll文件的名字空间:

using microsoft.directx;
using microsoft.directx.directsound;

  2.建立设备。在我们导入的microsoft.directx.directsound空间中,有个device的类。这个是表示系统中的声音设备。

device dv=new device();

  3.设置cooperativelevel。因为windows是多任务的系统,设备不是独占的,所以在使用设备前要为这个设备设置cooperativelevel。调用device的setcooperativelevel方法:其中,第一个参数是一个c

  在这个程序中,c

dv.setcooperativelevel((new uf()),cooperativelevel.priority);

  4.开辟缓冲区。对于上面的声音设备,他有个自己的缓冲区,叫主缓冲区。系统中,一个设备有唯一的主缓冲区。由于windows是多任务(又是这个!),所以可以有几个程序同时利用一个设备播放声音,所以每个程序都自己开辟一个二级缓冲区,放自己的声音。

  系统根据各个程序的优先级别,按照相应的顺序分别去各个二级缓冲区中读取内容到主缓冲区中播放。这里,我们为snd.wav开辟一个缓冲区。

  其中,第一个参数表示文件名(傻瓜都看出来了!),第二个就是需要使用的设备。

sec buf=new secondarybuffer(@"snd.wav",dv);

  5.接下来就可以播放啦。第一个参数表示优先级别,0是最低的。第2个参数是播放方式,这里是循环播放。

buf.play(0,bufferplayflags.looping);

  6.由于命令行程序没有消息循环,执行完代码就退出了,所以,我们需要暂停程序。

console.read();

  7.关键的部分已经完了,这里只是交代一下刚才的那个倒霉的new uf() 是什么东西。这个完全是为了应付setcooperativelevel的参数要求。我不知道这样做有什么附作用(各位如果因此把声卡烧了…………)

class uf:form{}

  8.代码写完啦~~~。下面可以编译了,这里编译比较复杂点。

csc /r:directxmicrosoft.directx.dll;directxmicrosoft.directx.directsound.dll dxsnd.cs

  这里,我把2个dll文件放在当前目录的directx目录下(这个是我自己建的,你只需要指出这2个文件的位置就可以了。)

  顺便把我的目录结构说明一下:

–dxsnd.cs
–snd.wav
–<directx>

–microsoft.directx.dll
–microsoft.directx.dll

  下面是完整代码:

//dxsnd.cs
using system;
using microsoft.directx;
using microsoft.directx.directsound;
using system.windows.forms;
namespace test1
{
 class test
 {
  public static void main(string [] args)
  {
   device dv=new device();
   dv.setcooperativelevel((new uf()),cooperativelevel.priority);
   sec buf=new secondarybuffer(@"snd.wav",dv);
   buf.play(0,bufferplayflags.looping);
   console.readline();
  }
  class uf:form{}
 }
}

ASP.NET 翻页后继续维持排序

要想实现翻页后继续排序,实现这样的效果: 比如共 15笔记录,每页显示10条
  则排序时:第一页将前10条记录排序,翻第二页时后五条再单独排序.

  要注意以下几点:

  1.如果数据很多,最好不要把数据集放到缓存中(viewstate),影响性能

  2. viewstate中存放上次是哪个e.expression并且存放此e.expressi

  示例如下:

  1.现有的排序事件是这样写的,这个是点击上面排序标题时用:

private void grdprojtrace_sortcommand(object source, datagridsortcommandeventargs e)
{
 this.grdprojtrace.currentpageindex = 0;
 dataview dv = 得到数据代码;
 string strsort = "";
 string strorder ="";//排序方式。0,降序,1升序
 if(viewstate["sortexpressti != null)
 {
  strsort = viewstate["sortexpresstion"].tostring();
  strsort = strsort.substring(0,strsort.length -1);
  strorder = viewstate["sortexpresstion"].tostring();
  strorder = strorder.substring(strorder.length -1);
 }
 if(e.sortexpression == "customername")
 {
  if(strsort != "customername")
  {
   this.viewstate["sortexpressti = ustomername0";
   dv.sort = "customername desc";
  }
  else
  {
   if(strorder == "0")
   {
    this.viewstate["sortexpressti = "customername1";
    dv.sort = "customername asc";
   }
   else
   {
    this.viewstate["sortexpressti = "customername0";
    dv.sort = "customername desc";
   }
  }
 }
 if(e.sortexpression == "fullname")
 {
  if(strsort != "fullname")
  {
   this.viewstate["sortexpressti = "fullname0";
   dv.sort = "fullname desc";
  }
  else
  {
   if(strorder == "0")
   {
    this.viewstate["sortexpressti = "fullname1";
    dv.sort = "fullname asc";
   }
   else
   {
    this.viewstate["sortexpressti = "fullname0";
    dv.sort = "fullname desc";
   }
  }
 }
 this.grdprojtrace.datasource = dv;
 this.grdprojtrace.databind();
}

  2.下面这个方法是自己写的,翻页事件中调用。

private void changepagedatabind()
{
 dataview dv = 得到数据代码;
 string strsort = "";
 string strorder ="";//排序方式。0,降序,1升序
 if(viewstate["sortexpressti != null)
 {
  strsort = viewstate["sortexpresstion"].tostring();
  strsort = strsort.substring(0,strsort.length -1);
  strorder = viewstate["sortexpresstion"].tostring();
  strorder = strorder.substring(strorder.length -1);
 }
 if(this.viewstate["sortexpressti != null)
 {
  if(strsort == "customername")
  {
   if(strorder == "1")
   {
    this.viewstate["sortexpressti = "customername1";
    dv.sort = "customername asc";
   }
   else
   {
    this.viewstate["sortexpressti = "customername0";
    dv.sort = "customername desc";
   }
  }
 }
 if(this.viewstate["sortexpressti != null)
 {
  if(strsort == "fullname")
  {
   if(strorder == "1")
   {
    this.viewstate["sortexpressti = "fullname1";
    dv.sort = "fullname asc";
   }
   else
   {
    this.viewstate["sortexpressti = "fullname0";
    dv.sort = "fullname desc";
   }
  }
 }
 this.grdprojtrace.datasource = dv;
 this.grdprojtrace.databind();
}

  上面两方法只要修改要排序的字段名,就可以直接调用了.

  1、方法很简单实用,这里就不说了。

  2、方法是这样用的:

private void grdprojtrace_pageindexchanged(object source, datagridpagechangedeventargs e)
{
 try
 {
  try
  {
   this.grdprojtrace.currentpageindex = e.newpageindex;
  }
  catch
  {
   this.grdprojtrace.currentpageindex = 0;
  }

  this.changepagedatabind();
 }
 catch(system.exception errws)
 {
  //异常
 }
}