c#

[WPF]Dispatcherで別スレッドからUIアクセス

Mohmongar
WPFでUIスレッドとは別のスレッドからUIを変更するときの作法。いつもやりかた忘れるのでメモ。formの場合のInvokeRequiredとinvokeに当たる。状況に応じてInvokeをBeginInvokeで非同期にするのもあり。VSでCheckAccessが入力補完対象にならないのはなぜだろう。 if (mycontrol.Dispatcher.CheckAccess()) { mycontrol.Content = "test"; } else { mycontrol.Dispatcher.Invoke((Action)(() => { mycontrol.Content = "test"; })); }

[WPF]コントロールの座標を調べる

Mohmongar
C# WPF環境で親コントロール座標系からの子コントロールのXY座標を求める。これだけのことなのに結構トリッキーな処理が必要。子cの座標系の(0,0)を親pの座標系に変換する、あれ?普通か・・というかWPFではコントロールの左上座標をしめすプロパティLeftとかTopととがないんだよな。 // // p ... parent control // c ... child control // Point d = c.TranslatePoint(new Point(0, 0), p); //

c#でmp3を鳴らす

Mohmongar
c#からmp3を鳴らす方法のうち、MCIsendStringを使う方法。play後にはちゃんとstopしてcloseしとかないと次鳴らせないので、playにnotifyをつけてWndProcで再生終了を受け取るのがポイント。これはFormで作ったからいいけど、[STAThread]じゃないと動かない模様。 public partial class mainform : Form { [System.Runtime.InteropServices.DllImport("winmm.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern int mciSendString(string command, System.Text.StringBuilder buffer, int bufferSize, IntPtr hwndCallback); string musicFile = ""; string aliasName = "MediaFile"; public mainform() { InitializeComponent(); } private void mainform_Load(object sender, EventArgs e) { musicFile = "test.mp3"; } private void button1_Click(object sender, EventArgs e) { string cmd; cmd = "open "" + musicFile + "" type mpegvideo alias " + aliasName; if (mciSendString(cmd, null, 0, IntPtr.

スクリーン上のマウス座標を取得し、WPFの論理座標に変換する方法

Mohmongar
スクリーン上のマウス座標を取得し、WPFの論理座標に変換する方法。マウス座標はデバイス座標なのでWPFで使うには論理座標に変換が必要。 System.Drawing.Point dp = System.Windows.Forms.Cursor.Position; System.Windows.Point wp = new System.Windows.Point(dp.X, dp.Y); // マウス座標から論理座標に変換 PresentationSource src = PresentationSource.FromVisual(this); CompositionTarget ct = src.CompositionTarget; System.Windows.Point p = ct.TransformFromDevice.Transform(wp);

C#で外部にあるDLL形式のresourceを動的に読み込む方法

Mohmongar
C#で外部にあるDLL形式のresourceを動的に読み込む方法。内部に埋め込む方法やサテライトDLLを使う方法はよくあったけど、こちらの方法はあまり紹介されてなかったので、メモ。 System.Reflection.Assembly asm; asm = System.Reflection.Assembly.LoadFrom("Test.resources.dll"); string[] manifests = asm.GetManifestResourceNames(); string manifest = manifests[0].Replace(".resources", string.Empty); ResourceManager rm = new ResourceManager(manifest, asm); string text = rm.GetString("String1"); // string resource

WPFでコードだけどバインドするときの例

Mohmongar
WPFでデータバインドをコードだけで実現する方法がわかりにくかったのでメモ。XAMLだとサンプル例は見つかりやすいんだけど、コードだけの例は少なかった。WPFの主旨からはずれるのかな。 バインドされるクラス側のコード(プロパティ変更の通知あり) Class Class1 { private int _test; public int test { get { return _test;} set { _test = value; OnPropertyChanged("test"); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } public Class1(int x) { test = x; } } コードだけでバインドする時 obj = new Class1(1); label1.DataContext = obj; label1.SetBinding(Label.ContentProperty, new Binding("test")); XAMLも使ってバインドする時のXAML側 <Label Content="{Binding test}" name="label1"/> XAMLも使ってバインドする時のコード側 obj = new Class1(1); label1.

c#でBITMAP画像マスク

Mohmongar
c#でBITMAP画像を別のBITMAPでマスクする。というか、特定色を透過色として、上から描画する。画像の論理演算かと思ったら違ったのでメモ。 Bitmap canvas = new Bitmap(inputFile); Graphics graph = Graphics.FromImage(canvas); Bitmap mask= new Bitmap(maskFile); mask.MakeTransparent(Color.White); // Transparent Color graph.DrawImage(mask, 0, 0, mask.Width, mask.Height);

System.Data.SqliteのExecuteScalar()の返り値(続き→間違い)

Mohmongar
c#のSystem.Data.Sqliteで検索結果から1つのスカラー値を獲得する時、ExecuteScalar()を使うが、テーブルの値はintでキャストできるない。count()とかmax()とかはぜんぶlong(=System.Int64)でキャストする。 // テーブルの値もintで受けることができない <--- 修正 cmd.CommandText = “SELECT data FROM table”; long x = (long)cmd.ExecuteScalar(); // <--- 修正 // 関数の戻り値は long で受けないと castエラー cmd.CommandText = “SELECT MAX(data) FROM table”; long x = (long)cmd.ExecuteScalar(); cmd.CommandText = “SELECT last_insert_rowid() FROM table”; long y = (long)cmd.ExecuteScalar(); 2014.6.25 修正。なぜかintで受けれないことが判明。前回は受けれたはずなのに。すいません。

System.Data.SqliteのExecuteScalar()の返り値

Mohmongar
c#のSystem.Data.Sqliteで検索結果から1つのスカラー値を獲得する時、ExecuteScalar()を使うが、その帰り値Object型をintでキャストするとエラーが出ます。stringからパースしてもだめ。結局longで正解。 SQLiteConnection conn = new SQLiteConnection(...); SQLiteCommand sqCommand conn.CreateCommand(); cmd.CommandText = "SELECT count(name) FROM result;"; // 指定されたキャストは有効ではありません。 int count = (int)cmd.ExecuteScalar(); // OK↓ long count = (long)cmd.ExecuteScalar();