==========
以下是引用 Harry 于 2009-3-24 8:53:55 发表的文字:
第一次崩溃:
做了一个ListBox,想通过回车键或鼠标双击把选中的项传递给变量,在MSDN上找了半天,没有找到ListBox有类似ItemSelected的事件,我还不会写控件事件,无奈只能加了个按钮,我崩溃。(dp2编目前端加拼音的多音字选择框,看似开始焦点在ListBox里面,但是想要按上下箭头选择相应的拼音就不行了,必须通过TAB才能把焦点放回ListBox,按回车能选中相应的选项,但是好像是通过控件的DoubleClick事件(双击控件任何位置都可以响应)实现的,老师在这里耍了个小花招,不太好用,再小小地嘲笑一下)
第二次崩溃
ListBox控件不好用,就想做个控制台程序吧,响应用户键盘输入来进行相应的选择,并判断用户输入是否在允许范围内,代码片断如下:
int a = Console.Read();
while (a-48< 1 || a-48> pyArr.Count) //汉字没有超过9个音的,所以pyArr.Count不会大于9
{
Console.WriteLine("超出范围,请重新选择");
a = Console.Read();
}
Console.Read()方法从输入流读入键,包括回车键,如果开始输入超出范围,while内的read会读取前一次输入后按下的回车键,并判断输入超出范围,晕,无奈又试了Readline()和ReadKey()方法,都不好用,我又一次崩溃了。这里应该有办法解决,感觉是我还不知道,小小地自嘲一下。
第三次崩溃
控制台程序不好用,没有办法,又回到窗体程序,拼音总算取出来了,想通过剪贴板和别的程序传递汉字和拼音,那么程序就要访问剪贴板,从剪贴板把字符串读出来没有问题,但是要把拼音写进去又出问题了,Clipboard.SetDataObject(pinyin, true),这个语句执行总是出错,把第二个参数改成false就没问题了,但这样程序退出后,在剪贴板里的内容也就没有了,上网搜了以下,一个外国网站上说Clipboard.SetDataObject()在2003系统上会出错,我现在用的就是2003系统,于是在XP上试了一下,没问题了,真的崩溃了!强烈地嘲笑微软一下。
这应该就是做程序要经历的吧,一会儿为自己精彩的解决办法沾沾自喜,一会儿为卡在什么小地方郁闷不已。
==========
谢谢你发现的问题,选择多音字的对话框在刚打开的时候,输入焦点不在那个listbox上,而在样本文字textbox上,所以用户如果用光标键,则只能在样本文字textbox中移动插入符,而不是在listbox中移动选择行标记。
“看似开始焦点在ListBox里面”这是你的观察不仔细了。并不是listbox有一个蓝色背景的行就是它拥有焦点,而是要看有没有一个虚线的方框包着。其实listbox无论在有无输入焦点的时候,里面都有一个蓝色背景的行。
问题已经解决。这里是我们测试不严,其实原来代码里面有一个切换输入焦点的语句,但是没有起作用而已。
现在用纯键盘操作的用户较少,这类问题一般不容易得到注意。流水加工数据的则对纯键盘操作很敏感,例如我们常说的“盲打”。
~~~
“...想通过回车键或鼠标双击把选中的项传递给变量,在MSDN上找了半天,没有找到ListBox有类似ItemSelected的事件...”
尽管不太清楚你的身份和所在单位,但是这些常识性的问题,还是可以切磋的。
准确说应当是在回车或者双击触发的时候,在里面获得listbox的选择项的Index位置,或者选择的字符串。很显然这是listbox的一个普通成员(属性),你读它的值就可以了,而不是要你去接管listbox的ItemSelected事件。
什么时候要“接管listbox的ItemSelected事件”呢?例如,你在界面上弄了个label,label里面要实时跟踪显示操作者在listbox中选择的行号。这跟操作者按回车没有根本没有关系。
要是在专业开发团队里,你这样说话就是胡言乱语了。
~~~
“...但是好像是通过控件的DoubleClick事件(双击控件任何位置都可以响应)实现的...”
你这个猜测很奇怪。从实践角度来说,如果回车的动作正好和双击的动作一样,那当然可以只写一个事件响应函数,挂到两个地方。或者一个地方调另外一个地方的已有的函数,调用方向不限。这不就是“代码复用”么,有什么问题?不明白有什么问题。
~~~
还有提醒一下回车键的问题。在Windows Form程序中,.NET的概念体系内,对话框是一个特别的东西,它不是一般的窗口。为了让程序员舒服,对话框基类里面已经实现了好多东西,有一些先入为主的概念。比方说,回车键是属于对话框整体的,有一个地方俘获,而一般不需要程序员在某个listbox里面去俘获。
另外感觉你基础很差,感觉上不是软件科班出身,建议看看Windows GUI规范,例如,对话框内,如果一个OK按钮被定义为这个对话框的缺省按钮,那么从概念上,在这个对话框内的任何控件内回车,都是相当于按了这个OK按钮。所以,从概念上来说,当然是由对话框来俘获这个动作,而不是由具体控件来繁琐地、逐一地留心俘获 -- 那样多累啊。
~~~
“...就想做个控制台程序吧,响应用户键盘输入来进行相应的选择...”
你的口头语“崩溃”,让人觉得矫情。不过,这次抓住你的一点,你上面这样说,到是真让我崩溃了一次。
同志,兄弟,你行行好,控制台是控制台,Form是Form,二者水火不容,这是第一天开始学Hello World程序的常识呢。
也就是说,控制台程序就绝对不是Form程序,Form程序就绝对不是控制台程序。在Form程序中,你要通过Windows的消息机制来获得任何键盘、鼠标等的信息,控制台的Read()函数根本不能用。就像你是男同志,不该进女厕所,对不对?
~~~
Clipboard.SetDataObject()向Windows剪贴板内写数据是没有错的。所说的在Windows 2003下会出问题,我暂时没有遇到过,有空我再测试一下。
编程序确实有不少诀窍,一些经验性的东西,例如,用C#编程,Windows GUI的程序,如果开发者早年有Windows API的经验,那就酷毙了。也好比,用SQL语句操纵一般数据库的时候,如果开发者早年有自己编B+树的经验,就太好了,那样开发者对数据库底层的运作机制有良好的直觉,在性能和优化方面不会犯错。
不过不是传说的那么邪乎。一般来说,清醒的头脑和宏观的意识比什么都重要。细节不一定要明白,但是大方向绝对不能错。