September 9,2008
Binding normal class to WPF control
通常一個簡單的List物件就可以讓它自動進行 binding
| ListBox list_box = new ListBox(); List string_list = new List(); list_box.ItemsSource = string_list; |
但是這樣子做有個問題,當你的string_list物件有了任何的增減或改變時
WPF的UI並不會自動的幫你更新list上的改變
有一個做法是使用下面的code,先將ItemsSource屬性清空再載入
強制它進行refresh的動作
| list_box.ItemsSource = null; list_box.ItemsSource = string_list; |
但是這樣子必需要手動來,有點麻煩,正港的懶人做法如下
| public class StringList : ObservableCollection<string>{} StringList string_list = new StringList(); list_box.ItemsSource = string_list; |
也就是宣告一個由ObservableCollection繼承下來的class來做為物件的container,由於ObservableCollection有實作INofiyPropertyChanged等interface,可以在物件有任何變化時,自動的通知WPF的UI進行update的動作
不過有一好沒兩好,由於這是全自動的,所以無法在UI thread以外進行對該container的操作,不然你就等著它吐Exception出來給你看囉
補充:
有人寫了一篇關於跨thread的WPF data binding 的文章,目前正研究中。
再補:
上面那篇最後的結論是,分成兩個List來操作,一個是專門用來binding的ObservableCollection,另一個則是真正用來處理增減、數值改變的List。上面再用一個Class包起來做統一的操作。不過根本之道還是得看微軟對於這個問題將來會不會推出什麼官方的解法了。
June 23,2008
SQL server compact 注意事項
但是要注意一件事,connection string 裡最好填的是絕對路徑
因為只要程式不小心換了 current directory 後
用相對路徑的data connection就找不到資料庫的家囉
June 21,2008
memcpy (IntPtr to IntPtr) in C#
直接呼叫 msvcrt.dll 中的 memcpy 即可
[DllImport("msvcrt.dll")]
private static extern IntPtr memcpy(IntPtr dest, IntPtr src, long size);
追加一個,不想要裝 msvcrt 的,可以改 call kernel32.dll 裡的 RelMoveMemory
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);
May 28,2008
Direct Memory Access in C#
public static bool Conv3x3(Bitmap b, ConvMatrix m) |
March 2,2007
MTA / STA 屬性影響.NET下的 COM Interop
MTA 和 STA 屬性通常會被定義在.NET程式的Main函式的Class上
而當在.NET平台下以Interop的方式載入COM物件的時候,其內部會根據你呼叫時程式的Thread定義,來採取不同的建構方式。
MTA >> CoInitializeEx(NULL, COINIT_MULTITHREADED)
STA >> CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)
Unknow >> CoInitializeEx(NULL, COINIT_MULTITHREADED)
其中以CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)所建立的COM物件,是無法在.NET環境下跨Thread使用的(你會得到一個Query Interface 失敗的 Exception)。所以若要在.NET下跨Thread使用COM物件,請記得將STA修改成MTA。
September 10,2006
用 Microsoft Visual C# Express 寫 MacOSX 的程式
之前就聽說C#像Java一樣可以跨平台執行,只是在MacOSX上必需要安裝Mono Framework。於是就實驗一下使用Microsoft VC# Express來編寫跨平台的GUI程式。沒想到還真的可以。這下子又多了一種開發MacOSX程式的方法了。
實作過程以及教學在以下網址:
http://www.iim.nctu.edu.tw/~toki/CSharpOnOSX/c%23osx.html
...繼續閱讀August 7,2006
當程式找不到 resource file 時該如何解決
根據微軟的說法,當有了以下的行為/情怳後,你編譯出來的程式不會有任何的warning,但是當執行時會出現找不到resource檔案的exception。
1、需要參照 resource 的 main windows form 的 class 不是整個專案中的第一個class。
2、main window form class 的名稱有改變過
微軟的解決方案是更改該resource檔案的build setting,把名字改成改變後的。但是有時候仍然無法解決這問題,這時候,手動指定resource檔案能夠有效(但是不治本)的解決這問題。
例:
System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(maagsServerForm::typeid));
改變成:
System::Resources::ResourceManager^ resources = gcnew ResourceManager("server.maagsServerForm", Assembly::GetExecutingAssembly() ) ;
則變成手動指定 "server.maagsServerForm.resource"此檔為做為 resource 檔案。
但需要注意的是,由於第一行程式通常是由 interface builder 產生,當用interface builder更動了任何 form 上的元件(增加/刪除/指定delegate)後,該行會被interface builder更新回去原來的狀態,這時候必需要手動再修改一次(所以說不治本)。
June 19,2006
加速 ListBox / ListView 加入新物件的方法
如果你有一堆的物件等著加入到 ListBox 或是 ListView 這些視窗元件時
記得先呼叫該元件的 SuspendLayout(),停止該物件的重繪更新
等到全部的物件都加入完成之後,再呼叫ResumLayout()
一口氣更新這些加入的物件
可以讓更新的動作快非常的多
另外,也可以使用AddRange來達到加速的效果
June 6,2006
Don't call constructor in constructor
Code:
public ref class ABC{
public:
ABC(){
m_pTestString = "TEST";
ABC(10);
}
ABC(int i){
Console::WriteLine("i={0}, Object={1}", i, m_pTestString);
}
void Test(){
Console::WriteLine(m_pTestString);
}
private:
String ^m_pTestString;
};
int main(array<:string ^> ^args)
{
ABC ^t = gcnew ABC();
Console::ReadKey();
return 0;
}
Result:
i=10, Object=
*m_pTestString 在ABC(int i)中被重新初始化,所以印不出值
June 3,2006
將傳統structure pointer 加入 .NET collection 物件中管理
很簡單......就是IntPtr
Struct testStruct{
int a;
int b;
};
testStruct *ts = new testStruct;
ArrayList^ tList = gcnew ArrayList();
tList->Add(gcnew IntPtr(ts));
-------------------------------------------------
取出:
testStruct *ts;
ts = (IntPtr^)tList[0]->ToPointer();
ts->a = 10;
ts->b = 10;