2016年8月28日 星期日

C# Winform 跨執行緒控制項作業 ( Cross thread UI Update)

當執行Windows Form程式和WPF 等UI form程式時

很常遇到 "跨執行緒作業無效: 存取控制項'ListItem'  " 類似的問題。


以下是理解後的說明:
1. 主控制項的執行緒不允許給子執行緒做存取,這會違反設計模式的封裝架構

2. 在編譯時能正常通過,表示微軟有提供可以走後門的方式Cross thread ui 程式碼如下:
Form.CheckForIllegalCrossThreadCalls = false; 

3. 一個符合安全的設計模式的跨執行緒程式碼如下:
        private void SetReturnValueCallbackFun(ref ListViewItem node, ExchangeData Data)
        {
            try
            {

                if (this.AllInfomation_listView_Service.InvokeRequired)
                {
                    this.AllInfomation_listView_Service.BeginInvoke((MethodInvoker)delegate () { this.AllInfomation_listView_Service.Items[0].SubItems[3].Text = Data.Text; ; });
                }
                else
                {
                    this.AllInfomation_listView_Service.Items[0].SubItems[3].Text = Data.Text;
                }
                //  AllInfomation_listView_Service.Items[0].SubItems[4].Text = Data.Text;
            }
            catch (Exception ex)
            {

            }

        }


當if (this.AllInfomation_listView_Service.InvokeRequired) 為true 時,表示不同執行緒,要透過委派的方式更新主執行緒的控制項資料。
否則當然就是同個執行緒所以可以執行存取控制項的值
※這是屬於匿名委派

4.以下是我的參考資料連結:

2016年8月4日 星期四

C# windows Form 程式使用SQLite ORM技術


範例檔案:下載
使用程式: Visual Studio 2015

如何在Windows Form 底下進行Sqlite 的ORM操作,以下是範例:


1.  建立一個Windows Form C#的專案程式。


2. 接著對專案按下滑鼠右鍵 -> NuGet 套件



3. 安裝 Sqlite-net 版本隨意。


4. 安裝完成後會發現多了 : SQLite.cs 與 SQLiteAsync.cs 兩個檔案,這兩個檔案就是ORM的函式庫。


5. 建立一個類別 ※可以參考範例檔案

6. 如下圖,我們已經可以進行SQLite ORM的 CreateTable<Class>() 操作


7. 進行編譯後 , 我們的123.db 檔案就產生了~ ,而且裡面有我們建立的表格。














2016年5月30日 星期一

ASP.Net MVC 將Controller 的 ViewModel 資料轉成 Javscript的資料

如題,當從Controller rturn(Model); 的時候資料會傳到View上,此時可以透過以下的方法將ViewModel的資料轉成Javascript的資料 以便於Alert



<script>
    var jsObject = @Html.Raw(Json.Encode(Model))
    alert(jsObject.QueryResult[0].mapping_tablename);
</script>


這邊要注意的是 當轉成 jsObject 的json物件時,如果要撈取對應的資料方法與在Model中Class呼叫的方法一致,以下是我在該範例的ViewModel。


//===================== 我的ViewModel - 第一層

public class LeaderboardResultTDDCModel
    {
        //頁面的查詢時間等資訊
        public LeaderboardTDDCQueryParam QueryInfom { get; set; }
        //股票搜尋結果類別表
        public List<LeaderboardTDDCModel> QueryResult { get; set; }


    }


//===================== 我的ViewModel - 第二層 QueryResult

public class LeaderboardTDDCModel
    {
        //股票對應表資料名稱
        public string mapping_tablename{ get; set; }

        //上升 六周計算
        public double RetailRate { get; set; }

        /// <summary>
        /// 各期散戶資料(50以下)
        /// </summary>
        public string RetailEachOfData { get; set; }
        //下降 六周計算
        public double LaregeRate { get; set; }

        /// <summary>
        /// 各期大戶資料(800以上)
        /// </summary>
        public string LaregeEachOfData { get; set; }

    }

2016年5月23日 星期一

C# ASP.net MVC 前端javascript傳遞到後端Controller 二維陣列傳遞方法


原始程式碼如下:

 var MaxGroup = 5;//群組數量

    var obj = [[]];   //===========================錯誤位置
    var tempGroupName = [];
    for (var i = 1; i < MaxGroup + 1; i++)
    {
        var tempStateList = [];
        //get checkbox
        for (var j = 1 ; j < 16; j++) {
            tempStateList.push($("#autokind_" + i + "_" + j).is(":checked"));
        }
        obj.push(tempStateList)
        tempGroupName.push($("#autokind_name_"+i).val());
    }

    var StoragePlaceParam = {
        'TableName': Param.TableName, //--使用者查詢的TableName
        'Date_Start': Param.Date_Start,
        'Date_End': Param.Date_End,
        'Combination': obj,
        'GroupName': tempGroupName,
        'GroupCount': 5
    };


    //------我們家的網址
    var root = "http://" + location.host;
    if (location.host.indexOf("localhost") == -1) {
        root = "http://" + location.host + "/" + location.pathname.split('/')[1];
    }

    $.ajax({
        type: 'POST',
        url: root + "/api/SingleStockApi/GetSingleStockExtentionKindChart",
        data: StoragePlaceParam,  //------------------------參數丟入
        success: function (data) {
 
        }
    });


以上透過Ajax 傳遞到後端後發生Combination 為null
在後端的Combination 型別為 List<List<bool>> 理論上應該要有值,後來發現是因為
var obj = [[]]; 不可以這樣寫 應該 寫成
var obj = [];

var obj =[[]]  實際上為 array  = [[null]]
在傳遞到後端時因為判斷到null 所以List<List<bool>> 會直接視為全為null
如果定義成obj =[] 實際上為 array = []


//=====================

2016年5月3日 星期二

C# MVC 3 以上 RenderSection 用法說明


RenderSection 用法說明:當頁面載入時會有順序問題,如果不加入section scripts 就在layout.html寫script將會發生錯誤,因為jquery pluging 尚未載入,所以加入section scripts後就會在plugin載入後才呼叫script


=====================================


    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>
@section scripts{
   
    <script>
        alert('123');
    </script>
   
    }

2016年5月2日 星期一

C# MVC SQLSERVER 矩陣轉置 - 靜態的行轉列

SQL 行轉列-靜態的行轉列

當在處理得到的集保戶庫存資料時,需要將資料Level (籌碼級距)做分類時就需要進行行轉列,如下圖原始資料



要將1 ~ 15 Level 的資料分類並且依照時間做條件,SQL如下
/****** SSMS 中 SelectTopNRows 命令的指令碼  ******/

SELECT [Year],[Month],[Day],
    SUM(CASE [Level] WHEN N'1' THEN [CHEP] ELSE 0 END) "Level1",
    SUM(CASE [Level] WHEN N'2' THEN [CHEP] ELSE 0 END) "Level2",
    SUM(CASE [Level] WHEN N'3' THEN [CHEP] ELSE 0 END) "Level3",
    SUM(CASE [Level] WHEN N'4' THEN [CHEP] ELSE 0 END) "Level4",
SUM(CASE [Level] WHEN N'5' THEN [CHEP] ELSE 0 END) "Level5",
    SUM(CASE [Level] WHEN N'6' THEN [CHEP] ELSE 0 END) "Level6",
    SUM(CASE [Level] WHEN N'7' THEN [CHEP] ELSE 0 END) "Level7",
    SUM(CASE [Level] WHEN N'8' THEN [CHEP] ELSE 0 END) "Level8",
SUM(CASE [Level] WHEN N'9' THEN [CHEP] ELSE 0 END) "Level9",
    SUM(CASE [Level] WHEN N'10' THEN [CHEP] ELSE 0 END) "Level10",
    SUM(CASE [Level] WHEN N'11' THEN [CHEP] ELSE 0 END) "Level11",
    SUM(CASE [Level] WHEN N'12' THEN [CHEP] ELSE 0 END) "Level12",
SUM(CASE [Level] WHEN N'13' THEN [CHEP] ELSE 0 END) "Level3",
    SUM(CASE [Level] WHEN N'14' THEN [CHEP] ELSE 0 END) "Level4",
    SUM(CASE [Level] WHEN N'15' THEN [CHEP] ELSE 0 END) "Level5"
FROM   [BochenLinTest].[dbo].[TDDC_9938]
Group By [Year],[Month],[Day]
order by Year,Month,day desc


結果圖片如下:

資料將會依照年月日,由小排到大,並且級距的資料變成Level 1~ 15

2016年4月30日 星期六

利用AJAX 呼叫 Controller 傳遞資料

JS部分:

 $(document).ready(function () {
                $('#privacyLink').click(function (event) {
                    event.preventDefault();
                    var url = $(this).attr('href');
                    //alert(url);
                    $('#privacy').load(url);
                });
            });


Controller 部分:

  public ActionResult PrivacyPolicy()
        {
            if (Request.IsAjaxRequest())
            {
                return PartialView();
            }

            return View();
        }







Html部分:

@Html.ActionLink("Show the privacy Policy", "PrivacyPolicy", null, new { id = "privacyLink" })

2016年4月20日 星期三

Entity FrameWork Database first MVC

以MVC架構做資料連結,以下的Msdn 說明得太棒了,所以趕緊記下來,Entity Framework MVC 架構忘記時照著做就記起來了 ~

https://msdn.microsoft.com/zh-tw/data/gg685489.aspx

2016年4月19日 星期二

asp.net MVC IIS 架設的網站提升速度的方法

在架設Asp.net 的MVC架構於IIS的網頁(站)時,因為MVC的機制是當使用者使用時將該網頁的.dll做編譯然後呈現給使用者,並且存活於一段時間快取,直到經過一段時間後才再給下一位使用者呼叫時進行編譯。


這邊的作法是將IIS 的網站永遠保持啟動,使使用者感覺不到編譯的等待時間

以下是作法

1.  開啟IIS 進到應用程式集區


2. 選擇當前網站使用的集區 -> 進階設定 -> AlwaysRunning



2016年3月29日 星期二

C# 已經建立的類別.cs之間傳值的方法 (也適用於Form 互相傳遞值 )

寫程式時有可能會發生以下情況:

當建立好一個類別A之後,之後的程式產生類別B,之後需要將"類別B"的值 傳給"類別A",雖然類別B是由A所產生,但是不知該如何將值回應給A做處理 (ex:A產生大量的Thread 類別B 最後 類別B的結果回傳給A)

此時可以使用Event Delegate的方式 建構類別A可接收資料的方法,並且在類別B產生一個呼叫Delegate的事件回應給類別A

程式碼大致如下:
分成1. Form1 2.Form2


//================Form1 設計畫面:




//================Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TransFormExample
{
    /// <summary>
    /// 說明:將資料從別的類別取得,先建構子類別的Delegate
    /// ※目前為單向,如果要由Form1 傳值給Form2
    ///        雙向:1.可以依照相同的方法在Form2進行接收Form1的資料
    ///    
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //Form2 變數名稱
        Form2 ReturnCallback = new Form2();

        private void button_Form1_Click(object sender, EventArgs e)
        {
            //顯示Form2
            ReturnCallback.Show();
        }

        private void Data(string GetStream)
        {
            //將傳回的字串放進
            this.Form1_textBox.AppendText(GetStream);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //讓MyMailWork掛載事件回傳Identifier的事件
            ReturnCallback.ReturnCallback += new Form2.ReturnDelegate(this.Data);
        }
    }
}


//================Form2設計畫面:




//================Form2.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TransFormExample
{
    public partial class Form2 : Form
    {
        //提供給主類別存放委派事件的位址
        public delegate void ReturnDelegate(string Stream);
        //回傳給主類別事件
        public event ReturnDelegate ReturnCallback;

        public Form2()
        {
            InitializeComponent();
        }

        private void button_Form2_Click(object sender, EventArgs e)
        {
            ReturnCallback(this.Form2_textBox1.Text);
        }
    }
}



範例程式下載  Visual 2010 windows form 程式 :

https://drive.google.com/file/d/0B42wM6w1VZR7bmVXcnVETENQNEE/view?usp=sharing

2016年3月8日 星期二

C# MVC專案, 無法叫用中斷點 未載入這個文件的符號

Dear all : 某次取得TFS專案後發現該問題,查了網路上許多方法後都無效,最後進行以下的操作才讓程式恢復Debug ,原本推測是bin 底下的pdb未進行同步,但發現清除專案在建置仍是最新的組件。
現在發現應該是IIS Catch住組件的資訊。

1.  專案 -> 屬性

2. Web -> 將專案URL 的初始位置 修改,※筆者原本URL為: http://localhost:9526 當改成 8429後就可以進行Debug了


因為專案屬於visual 2013 C# .netFrameWork 4.5.1 MVC  如果還是無法解決只能再另尋方法