WPFのDataGridで行単位でダブルクリックを受け取る。
<datagrid.rowstyle> <style targettype="DataGridRow"> <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick"/> </style> </datagrid.rowstyle>
コンボボックスのリストの中身を変更(ソートとか)した時にselectedItemを見失うのを防ぐ。Tagプロパティを一時保存に使用するのであまり美しくない?
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { var combo = (ComboBox)sender; object item = combo.SelectedItem; if (item == null) { combo.SelectedItem = combo.Tag; } else { combo.Tag = combo.SelectedItem; } }
c#でSqlite をつかっていた際、特定の条件で64bit数値が32bit化されることを発見。普通のselectでは発生せず、
create table ... as select ...
で発生。
System.Data.SQLite Net.1.0.108で発生。SQLite version 3.24.0.のコマンドラインツールからの実行では発生なし。python 3.5.1 sqlite3 2.6 で発生なし、なので、.Netライブラリ上でのみ起こるっぽい。
元のテーブル
create table test (id integer not null unique primary key, value integer not null);
に下図のような値が入っていた時、
create table tmp as select id,value,value+0 from test;
を実行したら、
となり、value欄の値が化けているのがわかる。-4394967295=0xffffffff付近で化けていることから、64bitが途中で32bit化しているっぽい。value+0となんらかの演算を行ったvalue+0カラムは正常な値になっている。
ちなみにselectだけの
select id,value,value+0 from test;
の場合、問題は起こらない。
C#でFormsを使ってプログラムする機会があって調べたメモ。メニューのあるアイテムの下層をひとつのグループとみなし、そのグループ中で一つだけチェックが入る前提で、メニューを選択した際にチェックをいれる処理を統一したもの。親menu1の下に子menu1_menu1,menu1_menu2,... があるとして、各メニューの処理時に同じCheckMenuExclusivelyを呼び出すことで排他的にチェックマークが入る。当然チェックを入れる以外の処理は別途必要。たぶん似たようなものはそこらに転がってるけど、子メニューを示すメソッドがItemsではなくDropDownItemsであったことため、しばし悩んだのでメモしておく。
void CheckMenuExclusively(object sender, ToolStripMenuItem upper) { foreach (ToolStripMenuItem item in upper.DropDownItems) { if (object.ReferenceEquals(sender, item)) { item.Checked = true; } else { item.Checked = false; } } } private void menu1_menu1_Click(object sender, EventArgs e) { CheckMenuExclusively(sender, menu1); }
ひさしぶりにWindowds formsのプログラムをC#で作成中にコントロールにデータバインドをしようとしたら、ListBoxなど一部のコントロールでは<INotifyPropertyChangedを使った更新が効かないことが分かったので、BindingListで使用したのでメモ。(というか本来ListboxにバインドできるのはSelectedIndex ,SelectedItem ,SelectedValue,Tagだけらしい)。
ここでBindingListを使わずにtestclassを直にDataSourceにバインドすると、PropertyChangedがnullとなる。
t = new testclass(); t.display = "one"; testdata = new BindingList<testclass>(); testdata.Add(t); listBox1.DisplayMember = nameof(display); listBox1.DataSource = testdata;
ついでによく忘れるので、INotifyPropertyChangedの書き方。
using System.ComponentModel; public class testclass : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName = "") { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public string _display; public string display { get { return _value; } set { if (value != _display){ _display= value; NotifyPropertyChanged(nameof(display)); } } } }
ほかにもいろんなやりかたがあるらしい。参考はこのページ「データ バインディング - .
C# WPF環境でDataGridをクリックした時のセル位置を求める。VisualTreeHelperを使ってDataGridCellとDataGridRowをたぐってcolumnとrowを調べる。formと違ってめんどくさい。他にも方法があるかもしんない。
// // DataGrid dg ... Clicked Control // Point pos ... Position in DataGrid axis // HitTestResult result = VisualTreeHelper.HitTest(dg, pos); if (result == null) { return; } DependencyObject dep = result.VisualHit; while (!(dep is DataGridCell || dep is DataGridRow)) { if (dep == null) { return null; } dep = VisualTreeHelper.GetParent(dep); } DataGridCell dgcell = null; int c = -1; if (dep is DataGridCell) { dgcell = dep as DataGridCell; c = dgcell.
MAPIでAppointmentを作る場合にTimeZoneの指定をする時のメモ。TimeZoneの元オブジェクトはApplication下にあるTimeZonesコレクションから参照する。
Using Outlook = Microsoft.Office.Interop.Outlook; Outlook.Application app = new outlook.Application(); Outlook.AppointmentItem apoItem = app.CreateItem(Outlook.OlItemType.olAppointmentItem) as Outlook.AppointmentItem; Outlook.TimeZones tzs = app.TimeZones; apoItem.StartTimeZone = tzs["Tokyo Standard Time"];
くわしくはHow to: Create an Appointment That Starts in the Pacific Time Zone and Ends in the Eastern Time Zoneを参照。
C#でEnumの列挙子の名前を表す文字列をenum値に変換する方法のメモ
enum Test { alpha, beta, gamma } Test ret; bool flag = Enum.TryParse<Test>("alpha", true, out ret); return ret; // == Test.alpha
c#で任意の型TがType型の変数tで与えられている場合のインスタンスを作る場合の方法。またはその配列のインスタンスを作る方法のメモ
// 任意型tのインスタンスの作成 Type t = typeof(***); var tInst = Activator.CreateInstace(t); // 型tの配列t[]のインスタンスの作成 Type t = typeof(***); Type ta = Type.GetType(t.toString()+"[]"); Int num; var tInst = Activator.CreateInstace(ta, num); // または Type t; Int num; var tInst = Array.CreateInstace(t, num); // 追加 var tInst = Activator.CreateInstace(t.MakeArrayType(1), num);
昔のDLLがBitmapしか対応してないので、System.DrawingのBitmapをWPFのBitmapSourceへ変換する。
[System.Runtime.InteropServices.DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); public BitmapSource BmpToWPFBmp(System.Drawing.Bitmap bitmap) { IntPtr hBitmap = bitmap.GetHbitmap(); BitmapSource source; source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); DeleteObject(hBitmap); return source; }