Quantcast
Channel: 午後わてんのブログ
Viewing all articles
Browse latest Browse all 420

WPFでもNumericUpDownが使いたい、簡単に作りたい

$
0
0

WindowsFormアプリのNumericUpDownコントロール
イメージ 9
水色の丸のところがそれ
便利だからこんなふうにたくさん使っていたのに
WPFにはない!
ので


WPFでNumericUpDownみたいなの
イメージ 1
数値の範囲は-10から10
下側の文字やボタンは確認用

これだけならXAMLだけでできる
イメージ 2
この中の11行目から24行目

イメージ 3
StackPanelの中にTextBoxとScrollBarを入れて作っている
ScrollBarのValueを基準にすると都合がいい、最小値や最大値、変更値も決められる
ScrollBarは上ボタンを押すとValueが下がって見た目と逆になるので180度回転させている
バインディングはTextBoxのTextにScrollBarのValue
これだけでok
といっても僕が思いついたんじゃなくて
Where is the WPF Numeric UpDown control? - Stack Overflow
https://stackoverflow.com/questions/841293/where-is-the-wpf-numeric-updown-control
ここに載っていたのをそのまま


あとは少し手間を掛けて
  • TextBoxフォーカス時にテキスト全選択する
  • 数値の変更はTextBoxやScrollBarの上でマウスホイールでもできるようにする
  • 数値以外は入らないようにする
このあたりはXAMLじゃなくてC#で書いてみたのが



using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
using System.Text.RegularExpressions;

//ScrollBarとTextBoxで簡易ヌメリックUpDown
//Where is the WPF Numeric UpDown control? - Stack Overflow

namespace _20180107_NumericUpDownのようなもの2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Title = this.ToString();
Button1.Click += Button1_Click;
NumericTextBox1.MouseWheel += NumericTextBox_MouseWheel;
NumericTextBox1.GotFocus += NumericTextBox_GotFocusSelectAll;
NumericTextBox1.TextChanged += NumericTextBox_TextChanged;
NumericScroll1.MouseWheel += NumericScroll1_MouseWheel;
}


//値確認用
private void Button1_Click(object sender, RoutedEventArgs e)
{
string str;
str = NumericTextBox1.Name.ToString() + "=" + NumericTextBox1.Text.ToString() + "\n";
str += NumericScroll1.Name.ToString() + "=" + NumericScroll1.Value.ToString();
var neko = NumericTextBox1.Text;
var neko1 = NumericScroll1.Value;
MessageBox.Show(str);
}


//[WPF] TEXTBOX でフォーカス時にマウスクリックでもテキストを全選択する v2 | rksoftware
//[WPF] TextBox でフォーカス時にマウスクリックでもテキストを全選択する | rksoftware
//TextBoxフォーカス時にテキスト全選択
private void NumericTextBox_GotFocusSelectAll(object sender, RoutedEventArgs e)
{
TextBox box = (TextBox)sender;
//box.SelectAll();
this.Dispatcher.InvokeAsync(() => { Task.Delay(10); box.SelectAll(); });
}


//のぶろぐ[WPF] テキストボックスに数字以外は受け付けない簡単な方法
//正規表現で数値以外は削除using System.Text.RegularExpressions;
private void NumericTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox box = (TextBox)sender;
double d;
if (!double.TryParse(box.Text, out d))
{
box.Text = Regex.Replace(box.Text, "[^0-9-]", "");
}
}

//C#のWPFで名前からコントロールを取得する - Ararami Atudio
//TextBox上でマウスホイールを回転させた時にスクロールバーの値を上下させる
private void NumericTextBox_MouseWheel(object sender, MouseWheelEventArgs e)
{
TextBox textBox = (TextBox)sender;
Binding binding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);
ScrollBar scrollBar = (ScrollBar)this.FindName(binding.ElementName);//名前から取得
if (e.Delta > 0)
{
scrollBar.Value++;
}
else
{
scrollBar.Value--;
}
}

//ScrollBar上でマウスホイールを回転させた時にScrollBarの値を上下させる
private void NumericScroll1_MouseWheel(object sender, MouseWheelEventArgs e)
{
ScrollBar sb = (ScrollBar)sender;
if (e.Delta > 0)
{
sb.Value++;
}
else
{
sb.Value--;
}
}
}
}




TextBoxフォーカス時にテキスト全選択するにはGotFocusイベント時に
SelectAllメソッドを実行すればいいけど
クリックで選択したときにも全選択したい場合はこれだとできなくて
[WPF] TEXTBOX でフォーカス時にマウスクリックでもテキストを全選択する v2 | rksoftware
https://rksoftware.wordpress.com/2016/09/06/001-48/
[WPF] TextBox でフォーカス時にマウスクリックでもテキストを全選択する | rksoftware
https://rksoftware.wordpress.com/2016/06/17/001-38/
こちらで紹介されていた方法で
イメージ 4
こう
InvokeAsyncとかTask.Delayとか初めて使った、全然理解できていない



マウスホイールでScrollBarの数値変更
イメージ 5
ScrollBarのMouseWheelイベント時にイベントのパラメーター?のeのDeltaの値を見てValueに足したり引いたりするだけ


次はTextBoxの上でマウスホイールを動かした時
イメージ 6
同じようにMouseWheelイベント時にScrollBarのValueを変更すればいいんだけど
どうやってそのScrollBarを取得すればいいのかなあってとこ

XAMLのほうでバインディングしていて対象はElementNameでしているから
TextBox textBox = (TextBox)sender;
Binding binding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);
こうしてBindingOperationsのGetBindingでTextBoxのBindingを取得して
そのElementNameからScrollBarの名前までは取得できたんだけどそこからわかんなくて
FindNameメソッド、MainWindowにもあるんだねえ

名前からの取得以外だとTextBoxのTagプロパティにScrollBarを入れておくってのもいいかな



TextBoxに数値以外は入らないようにする
イメージ 7
これは全くわからなかったので即ググって
のぶろぐ[WPF] テキストボックスに数字以外は受け付けない簡単な方法
http://shen7113.blog.fc2.com/blog-entry-22.html
こちらから
これも理解できていないw
こうすると文字のキーを押しても無視されるようになる

結果
イメージ 8
できましたー



参照したところ
Stack Overflow - Where Developers Learn, Share, & Build Careers
https://stackoverflow.com/

rksoftware | C#でいろいろ調べたりしたことのメモ
https://rksoftware.wordpress.com/

Android Apps - Ararami Atudio
https://araramistudio.jimdo.com/

のぶろぐ
http://shen7113.blog.fc2.com/
ありがとうございます



至った経緯
Extended WPF Toolkit
Extended WPF Toolkit™ Community Edition - Home
http://wpftoolkit.codeplex.com/
Extended WPF Toolkitっていう便利なものの中にNumericUpDownみたいなのがあって

イメージ 10
これが使えればいいんだけど
今のバージョンだとバグがあるみたいで

イメージ 11
アプリの対象を64bitにするとデザイン画面に表示されない

イメージ 12
デバッグからリリースにしてデバッグ開始すると

イメージ 13
なにこれこわい
こんな感じなので使うのを諦めた


次にPixtack紫陽花2ndのときにはあちこち参考にして、ユーザーコントロールで作ったのがあるけど、手間がかかった割にイマイチなできに終わったのでそれも使いたくなくて、簡単に作る方法ないかなあって探していたのよねえ、そこでStack Overflowで見つかったのがScrollBarを使う方法!
今回は満足なものができたので記事にした次第


C#
今まではVisualBasicばかりだったけど、今回はC#
バブルソートの記事以来2回目かな
WPFでわからないことをググるとVBよりC#のほうが多いからC#のほうがラクかも
VBはエクセルのVBAがあるからWindowsアプリはC#にしようかなあ

Numericはヌメリック派です!
nullはヌルなんだからNumericはヌメリックなんだよなあ
でもASUSはアサス派





Viewing all articles
Browse latest Browse all 420

Trending Articles