2016年1月

WPF中Listbox相关

"Listbox滚动"和"Modbus简单介绍"

Listbox中加入滚动条

<ListBox 
    ItemsSource="{Binding}" 
    ScrollViewer.VerticalScrollBarVisibility="Visible">
</ListBox>

Listbox滚动到最后

lstBox.SelectedIndex = lstBox.Items.Count -1;
lstBox.ScrollIntoView(lstBox.SelectedItem) ;

myListBox.Items.MoveCurrentToLast();
myListBox.ScrollIntoView(myListBox.Items.CurrentItem);//这个未测试

说一句还是google好用啊,使用英文词搜索效率太高。

将十进制数变为浮点数

浮点数符合IEEE 754 单精度定义

演示一个示例:将十进制数17.625编译成二进制数

  1. 十进制形式17.625表示成二进制形式的浮点数

先求出整数部分的二进制表示,通过除二取余(倒着取)得到17的二进制10001B
再求出小数部分的二进制表示,通过乘二取整,得到0.625的二进制0.101B
所以十进制形式表示的17.625的二进制形式的浮点数为10001.101B

  1. 移位求指数

10001.101B向左移,直至小数点前只剩下一位,得到1.0001101B,而10001.101B=1.0001101B × 2^4,所以指数部分为4,加127,变为131,131的二进制表示为1000001B

  1. 计算尾数

拿掉1.0001101B的小数点前的1得到尾数0001101B,(因为小数点前必为1,所以IEEE规定只记录小数点后面的就可以),针对23位尾数的重要说明:第一位(即隐藏位)不编译。隐藏为是分隔符左侧的位,此位通常被设置为1并抑制。

  1. 符号位定义

正数的符号位为0,负数的符号位为1

  1. 转化为浮点数

1位符号8位指数23位尾数

Visifire控件使用记录

要用到"折线图"表现趋势,赶紧搜了下"WPF 折线图",发现了"Visifire"这个东东,花了一天的时间熟悉了下,从数据看中把数据拿出来,然后画成折线图


下载

这里,找到所需要的visifire下载下来,我下载的是WPF版本
没有图看起来效果不好啊,类似下面这种都可以做
类似这样的

哈哈

一看就很专业是不是。。。。

学习

里面自带的例子就非常好,所以这先看看例子,改改就能用了。

自带的例子中,代码大都在.cs文件中,而官网上的例子可以看写在XMAL中的例子。

    /// <summary>
    /// Function to create a chart,创建一个图标的方法
    /// </summary>
    public void CreateChart()
    {
        // 创建一个chart的实例
        Chart chart = new Chart();
        chart.Width = 500;
        chart.Height = 300;
        //动画使能
        chart.AnimationEnabled = false;

        // 实例化标题
        Title title = new Title();

        // Set title property
        title.Text = "Visifire Sample Chart";

        // Add title to Titles collection
        chart.Titles.Add(title);
                    
        // Create a new instance of DataSeries
        DataSeries dataSeries = new DataSeries();  

        // Set DataSeries property
        //Line是折线,spline是有点弧度的曲线,从`RenderAs`中可以选择折线图、直方图、饼图等等了,反正很多图种
        //dataSeries.RenderAs = RenderAs.Line;
        dataSeries.RenderAs = RenderAs.StreamLineFunnel;
        // Create a DataPoint,数据点。一个横坐标,一个纵坐标。
        DataPoint dataPoint;

        for (int i = 0; i < 10; i++)
        {
            // Create a new instance of DataPoint
            dataPoint = new DataPoint(); 
            
            // Set YValue for a DataPoint
            dataPoint.YValue = rand.Next(0, 100); 

            // Add dataPoint to DataPoints collection.
            dataSeries.DataPoints.Add(dataPoint); 
        }

        // Add dataSeries to Series collection.
        chart.Series.Add(dataSeries);

        // Add chart to LayoutRoot,`LayoutRoot`是`XMAL中的Grid`
        LayoutRoot.Children.Add(chart);
    }

感觉很简单,拿过来用就行了。把图表类型RenderAs改为你所需要的,把DataPoint填充上你的数据。
在其他的例子中感觉需要记录的属性说下

// Set chart properties
//很明显就是滚动使能
chart.ScrollingEnabled = true;
//平面还是3D喽
chart.View3D = true;

//这是坐标轴
// Create a new Axis
Axis axis = new Axis();
// Set axis properties
axis.IntervalType = IntervalTypes.Days;//坐标轴间隔的类型,如果横坐标是通过时间来分割的,这个会非常有用
axis.Interval = 1;                    //坐标轴两点间隔多大,像这里是1,就代表,两点间隔一天。
axis.StartFromZero = true;            //是否从零开始
// Add axis to AxesX collection
chart.AxesX.Add(axis);                

dataSeries.XValueType = ChartValueTypes.DateTime;    //x轴数据的类型,这里是DateTime,上面坐标轴分割是通过IntervalTypes.Days,就可以正确分割了。

//事件处理程序,和普通的使用起来没有区别
title.MouseLeftButtonDown += new MouseButtonEventHandler(title_MouseLeftButtonDown);
dataPoint.MouseLeftButtonUp += new MouseButtonEventHandler(dataPoint_MouseLeftButtonUp); 

那些都在代码中,看累了休息下

//动态更新
for (Int32 i = 0; i < 5; i++)
        {
            // Update YValue property of the DataPoint
            chart.Series[0].DataPoints[i].YValue = rand.Next(-80, 100); // Changing the dataPoint YValue at runtime
        }

有很多属性不知道是吧,来这里看,直接当成属性用就行了,名字肯定差不多。好吧,真正的官方文档在这里,看起来很爽。


Gauges是仪表或者类似进度条之类的东西,用起来也显得很专业。使用和chart类似,非常简单
图形的话就是这样
展示

Gauge gauge1 = new Gauge();
//Type控制两种类型,有  Linear 或 Circular可选
gauge1.Type = GaugeTypes.Linear;
gauge1.BorderBrush = new SolidColorBrush(Colors.Aqua);
gauge1.BorderThickness = new Thickness(2,2,2,2);
        
BarIndicator barIndicator1 = new BarIndicator();
barIndicator1.Value = 50;
gauge1.Indicators.Add(barIndicator1);
LayoutRoot1.Children.Add(gauge1);

上面代码展示了创见左边的类型,下面展示右边的代码

Gauge gauge2 = new Gauge();
gauge2.Type = GaugeTypes.Circular;
NeedleIndicator indicator1 = new NeedleIndicator();
indicator1.Value = 50;
gauge2.Indicators.Add(indicator1);

BarIndicator indicator2 = new BarIndicator();
indicator2.Value = indicator1.Value;
gauge2.Indicators.Add(indicator2);

 LayoutRoot2.Children.Add(gauge2);

发现用XMAL来写貌似逻辑更加清楚些:

<Grid x:Name="LayoutRoot3" Grid.Row="1" Grid.Column="0" Margin="10">
        <vg:Gauge Type="Circular" >
           <vg:Gauge.Indicators>
                <vg:BarIndicator Value="80" Style="{StaticResource BarStyle}"></vg:BarIndicator>
           </vg:Gauge.Indicators>
        </vg:Gauge>
</Grid>

上面有个style属性是在app.config中定义的,用来更改显示的样子

xmlns:gauges="clr-namespace:Visifire.Gauges;assembly=WPFVisifire.Gauges"
         StartupUri="MainWindow.xaml"
<Style x:Key="BarStyle" TargetType="{x:Type gauges:BarIndicator}">
         <Setter Property="StartWidth" Value="0"></Setter>
          <Setter Property="Placement" Value="Inside"></Setter>
</Style>

Dashboard

哈哈,看完了chartGauges感觉非常还可以,然后又看了看还有两个文件夹Dashboard,一看Dashboard中的代码是通过MVVM设计模式写的,发现宝了,晚上看看,明天再写。


C#关于数据库基础知识

今天复习了一下数据库,记录下。


连接到数据库

  1. vs可能从2013吧,自带了一个localDB数据库,使得开发人员不用再装庞大的sqlserver。可以使用localDB完成一些功能。

sqlserver对象资源管理器添加sqlserver服务器,服务器填入(localDB)\v11.0,在2015中貌似变为了(localdb)\MSSQLLocalDB

  1. 连接字符串

这个可能是最令人迷糊的了。先放几种方式,那种都可以

data source=(local);Integrated Security=True;initial catalog=db
--
Data Source=server;Initial Catalog=db;User ID=uasername;Password=xx;
--
Server = server;Database = db;User ID = Username;Password = Password;
...
--

还能有各种组合,反正就是组合服务器、数据库、用户密码或者windows身份验证,选择一种使用就行了。

  1. 最常见的还是在配置文件.config中进行配置

<configuration>
    <connectionStrings>
      <clear />
      <add name="conn" 
       connectionString="Valid Connection String;" />
</connectionStrings>

在代码中获取进行使用

ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[name];
// If found, return the connection string.
if (settings != null)
    connectionString = settings.ConnectionString;
//在使用上述这小段代码时,要添加对System.Configuration.dll`的引用

连接到数据库服务器是非常耗时的,ADO.NET使用连接池的语法来减小开销。使用using语句可以自动释放资源。

using (SqlConnection connection = new SqlConnection(
  "Integrated Security=SSPI;Initial Catalog=Northwind"))
    {
        connection.Open();      
        // Pool A is created.
    }

执行sql命令

sqlcommand有四个方法:

一般我反正使用前三个就行了。在这里反正我一直使用sqlHelper
这里面有.NET Framework和数据库类型对应,在设计数据库时非常有用。
展示一小段代码:

connection.Open();

string queryString = "INSERT INTO Customers " +
  "(CustomerID, CompanyName) Values('NWIND', 'Northwind Traders')";

SqlCommand command = new SqlCommand(queryString, connection);
Int32 recordsAffected = command.ExecuteNonQuery();

dataset datatable dataadapter

先看一张图

dataset:表示整个数据集,其中包含对数据进行包含、排序和约束的表以及表间的关系
datatable:表示一个内存中数据表
dataadpater:用于从数据源检索数据并填充 DataSet 中的表,和datareader组成从数据库中拿数据的方法
DataAdapterFill 方法用于使用 DataAdapterSelectCommand 结果填充 DataSetFill 使用填充的 DataSet、和 DataTable 对象(或要使用从 SelectCommand 中返回的行来填充的 DataTable 的名称)作为它的参数。
下面一段代码就明白了;

string queryString =  "SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");

刚开始学习的时候啥也不懂,很多东西没弄明白,现在虽然也有很多不明白的。但总比以前好多了。

作业完成!!!

前两天考试完成,这两天终于把作业做完了,感觉像松了很大的一口气。。。


准备将自己做的东西稍微总结一下,虽然没什么技术含量。。。

关于进制的知识

由于所做的工作都是基于串口进行编程,所以在一开始就先说下C#中关于进制转换的方法。

  1. 十进制输出称为十六进制字符串

    int num = 1;
    Console.WriteLine(num.ToString("X4"));
输出为 "000B",其中`X4`代表`4个位的大写的十六进制`,如果换为`"x2"`,那么输出就变成了`0b`,我想应该很好了解了。
  1. 十进制变为16进制的byte
    首先应该知道int类型50x5是没有区别的,就像100xA一样和byte关键字代表一种整型,存储数据大小是0-255。明白了就清楚了,所以直接类型转换就好了。

    int num = 10;
    byte b = byte.Parse(num.ToString());
    byte c = (b)num;
所以不用去考虑那么多,我刚开始的在想一个int类型的数据,怎么变成16进制的byte呢,把自己给绕晕了。事实就是byte就是一种存储0-255大小的整数。
  1. 说说右移操作符>>的作用,展示一段代码就明白了

ushort num = 0x1011;
byte a = (byte) (num >> 8);
byte b = (byte) num;

输出a0x10,b0x11>>就是将对应的二进制右移。0x1011对应的二进制为0001 0000 0001 0001,右移8位就成了0001 0000就是a的值,b就是取低八位了。

  1. 收到的串口数据经常是byte数组,怎么把byte数组中的数据进行打印呢

byte[] vals = { 0x01, 0xAA, 0xB1, 0xDC, 0x10, 0xDD };
Console.WriteLine(BitConverter.ToString(vals));
  1. 经常要操作进行多线程操作,线程池怎么使用呢?

ThreadPool.QueueUserWorkItem(o =>print());
private static void print()
{
    while(True){
        Console.WriteLine("xxx");
        Thread.Sleep(1000);
    }
}
  1. 完成一件工作了,要推出怎么办呢?就是说怎么取消线程池呢,比如说计数到10退出,要使用到CancellationTokenSource

CancellationTokenSource cts = new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(o =>print());
private static void print(CancellationTokenSource cts)
{
    while(True){
        if(cts.Token.IsCancellationRequested)
        {
            break();
        }
        Console.WriteLine("xxx");
        Thread.Sleep(1000);
    }
}
//在外部设置 cts.Cancel();就可以发出取消通知。
  1. 调用线程必须为STA,因为UI需要

public delegate void DeleFunc();
public void Func()
{

//使用ui元素

}


线程函数中做如此调用:

System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,new DeleFunc(Func));

东西不多,也是一些比较基础的,还是要好好打基础啊。今天重新看了看数据库的知识,大二大三一直在做,好久不做了。晚安。

考试完成!!!

今天终于所有科目的考试都完成了,感觉整个人都不好了。一点意思没有。
接下来几天开始更新博客,主要两个方面:1、Modbus协议相关的知识,和分享一个.NET处理Modbus的协议文件,使用起来超级方便;2:GMap.NET总结和Mavlink协议的总结,前面写的Mavlink协议方面都是直接看的文档,没有结合程序,所以读起来都是一头雾水,接下来努力把MissionPlanner中关于Mavlink 的协议部分总结一下。
最近的几个周都坚持使用极简番茄这款软件,还是比较方便的。

番茄工作法我的理解:

    1. 25分钟(或其他)为一个番茄钟,这时间段内不允许做其他的事情,只能做你规划的事情。如果因为其他原因被打断,则这个番茄钟失效。

    1. 完成一个番茄之后休息5分钟,完成四个番茄休息30分钟。

    2. 一件工作最好不要太多的番茄,如果太多进行分割。

    我并没有按照标准的番茄工作法进行工作,去安排我的任务,前段时间我的任务是复习,我也不是很确定需要多少个番茄才可以完成复习工作,如果你知道你需要多少时间的话,那么最好为你的工作分配确切的番茄个数,否则就在一个番茄钟之内尽力去做就行了。人们现在将自己的失败归咎于没有好好把时间利用起来,比如:我挂科了,我没有好好复习(好吧,这个例子不大恰当在这个时候);我用了很长时间都没读完一本书....我想如果你也有这样的困惑的话也用这个方法做下,没准会有神奇的收获。
    我想这段时间内我感觉比较高兴的事情就是我终于买了自己想买的相机。接下来的时间那就是好好利用起来,不断学习,拍照and后期。
    这是一篇没有价值的文章,仅仅因为我想开个头,为新的一年。