一些C#小细节的碎碎念

最近项目结束了, 开发了其中的一个小系统,用作Video Processing, 我主要负责一些C#的界面开发,项目中学习了很多东西,写一篇文章来回顾一下学到的东西和遇到的问题吧。
从来没尝试过问答体,这次试试吧。

Q: 为什么要用C#做界面,相关的项目的内容是什么?
A: 因为项目涉密,所以不能开源,也不能说的太细。总之在项目中我主要负责的是这个系统的前端部分,因为算法以及很多业务逻辑的框架都搭好了。核心的算法是用C/C++写的混合模块,直接封装了dll,同时需要用到一些图像处理的库,考虑再三,决定搭配OpenCV的一些成熟的算法。
由于MFC这种已经老得掉渣的东西是有情怀的leader所摒弃的,加上之前用C#做过一个的小项目,于是就采用OpenCV for C#: Emgu 来调用算法并且用青出于WinForm而胜于WinForm的C#来完成系统。

Q: 开发工具和开发环境?C#中的设计UI的细节都有哪些?
A:第一个问题很简单,Win7 + VS2013 或者更新版本就好,完全安装了VS2013之后会有一个叫 Blend for VS 2013 的IDE,这个功能很强大,适用于界面的调整和设计,如果你用的是双屏,那么左边一个VS,右边打开Blend,爽得很! 

第二个问题比较宏大,我的切入点比较小,就用一些私人的见解来写好了。本质的讲, C#是完全面向对象的,因为之前的C++和Java中已经掌握的一些OOP/OOD的思路都可以直接用,C#的源文件后缀名是.cs,而与界面的后缀名是.xaml。在.xaml中,有很多C#已经集成好了的控件(widget),比如经典的button, image, progressbar, Text, Checkbox, DocumentView, ListView, ScrollViewer等等,同时还提供了Canvas(画布),这样就可以直接拖动控件到画布上进行设计,当然也可以写代码实现,做过界面开发的人都懂的。

Q: 遇到的问题有哪些?
A: 这个问题就更多了,我分成几个部分来回答。
1. 设计一个Image控件,希望能实现点击Image中显示的图片并且响应点击事件。
- 遇到的第一个问题其实很基本,总结一下,换个表述其实就是:把Image对象做出和Button一样的效果。因为如果是修改Button的Background的话,当鼠标放到Button上的时候,Button会编程原来的样子,不好看,所以希望Image对象也响应点击事件。 解决的办法其实很简单,就在.xaml文件中对应的Image控件的定义里,重新定义MouseDown()事件即可

2. BitmapImage  Image Bitmap的互转
这个问题很重要,因为在做的过程中出现了大量在这三种格式互相转换的情况。在stackoverflow上找到了很多答案, 

比如:BitmapImage -> Bitmap

         public static Bitmap Stream2Bitmap( BitmapImage bitmapImage)
        {
            using (MemoryStream outStream = new MemoryStream ())
            {
                BitmapEncoder enc = new BmpBitmapEncoder ();
                enc . Frames. Add( BitmapFrame. Create(bitmapImage));
                enc . Save(outStream);
                System . Drawing. Bitmap bitmap = new System . Drawing. Bitmap (outStream);

                return new Bitmap(bitmap);
            }
        }

Bitmap -> Image
Image<Rgb, Byte> imageNew = new Image<Rgb, Byte>(currentBitmap);

Image -> BitmapImage
需要先将图片写到Buffer中,在按照BitmapImage的格式写回
         public static BitmapImage Buffer2Bitmap( byte [] rgbFrame, int width, int height, int streamlength, int bpl)
        {
            stream = new MemoryStream(streamlength);
            bw = new BinaryWriter(stream, System . Text. Encoding .Default);
            bw . Write('B' ); bw .Write( 'M' ); bw. Write(bpl * height + 54 );
            bw . Write(0 ); bw .Write( 54 ); bw. Write( 40);
            bw . Write(width); bw .Write(height);
            bw . Write((ushort ) 1); bw . Write((ushort ) 24);
            bw . Write(0 ); bw .Write(bpl * height); bw. Write( 0);
            bw . Write(0 ); bw .Write( 0 ); bw. Write( 0);

            byte [] data = new byte [bpl * height];
            int gIndex = width * height;
            int bIndex = gIndex * 2 ;

            for (int y = height - 1 , j = 0 ; y >= 0; y -- , j++ )
            {
                for (int x = 0 , i = 0; x < width; x++ )
                {
                    data[y * bpl + i ++] = rgbFrame[bIndex + j * width + x];    // B
                    data[y * bpl + i ++] = rgbFrame[gIndex + j * width + x];    // G
                    data[y * bpl + i ++] = rgbFrame[j * width + x];  // R
                }
            }

            bw . Write(data, 0 , data .Length);
            bitmapImage = new BitmapImage();
            bitmapImage . BeginInit();
            bitmapImage . StreamSource = stream;
            bitmapImage . EndInit();
            return bitmapImage;
        }
3. 进度条(progressbar)控件的使用
首先在.xaml文件中拖入一个进度条控件,如下图:进度条命名为ProgressBar1
         < ProgressBar HorizontalAlignment = "Right" Name= "ProgressBar1" Height ="7" Grid.Row ="4">
然后在对应的.cs文件中定义一段代码,用于加载本进度条:

         private void pbControl() // update progressbar
        {
            string pg = null;

            for (int i = 0 ; i <= 100; i ++ )
            {
                pg = "当前进度: " + i + "%." ;

                if (! this .ProgressBar1 . Dispatcher. CheckAccess())
                {
                    //更新UI界面
                    this .ProgressBar1 . Dispatcher. Invoke(
                        DispatcherPriority . Normal,
                        new UpdateProgressBarDelegate (( int progress) =>
                        {
                            this .ProgressBar1 . Value = progress;
                            this .TextBoxForProgressBar . Text = pg;

                            if (100 == i)
                            {
                                Thread .Sleep( 1500 );
                                this .ProgressBar1 . Value = 0;
                                this .TextBoxForProgressBar . Text = "完成!" ;
                            }
                        }),
                         i);
                    Thread .Sleep( 500 );

                }
            }
        }
4. 和用户交互,弹出简易的系统对话框
            string messageBoxTitle = "系统提示" ;
            MessageBoxButton button = MessageBoxButton . OK;
            MessageBoxImage icon = MessageBoxImage . Warning;
            MessageBoxResult GetUserResult = MessageBox . Show(messageBoxText, messageBoxTitle, button, icon);

            switch (GetUserResult)
            {
                case MessageBoxResult . Yes: break ;
                default : break ;
            }
系统还在继续的更新,我也继续学习新的方法, 积累到一定程度了再分享吧。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值