午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

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

追記
簡単じゃないのはこっち
追記ここまで
 
 
WindowsFormアプリのNumericUpDownコントロール
イメージ 9
水色の丸のところがそれ
便利だからこんなふうにたくさん使っていたのに
WPFにはない!
ので
 
 
WPFでNumericUpDownみたいなの
イメージ 1
数値の範囲は-10から10
下側の文字やボタンは確認用
 
これだけならXAMLだけでできる

f:id:gogowaten:20191211183916p:plain

この中の11行目から24行目
イメージ 3
StackPanelの中にTextBoxとScrollBarを入れて作っている
ScrollBarのValueを基準にすると都合がいい、最小値や最大値、変更値も決められる
ScrollBarは上ボタンを押すとValueが下がって見た目と逆になるので180度回転させている
バインディングはTextBoxのTextにScrollBarのValue
これだけでok
といっても僕が思いついたんじゃなくて
ここに載っていたのをそのまま
 
 
あとは少し手間を掛けて
  • 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
        //https://rksoftware.wordpress.com/2016/09/06/001-48/
        //[WPF] TextBox でフォーカス時にマウスクリックでもテキストを全選択する | rksoftware
        //https://rksoftware.wordpress.com/2016/06/17/001-38/
        //TextBoxフォーカス時にテキスト全選択
        private void NumericTextBox_GotFocusSelectAll(object sender, RoutedEventArgs e)
        {
            TextBox box = (TextBox)sender;
            //box.SelectAll();
            this.Dispatcher.InvokeAsync(() => { Task.Delay(10); box.SelectAll(); });
        }

        //のぶろぐ[WPF] テキストボックスに数字以外は受け付けない簡単な方法
        //http://shen7113.blog.fc2.com/blog-entry-22.html
        //正規表現で数値以外は削除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
        //https://araramistudio.jimdo.com/2016/12/05/wpf%E3%81%A7%E5%90%8D%E5%89%8D%E3%81%8B%E3%82%89%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B/
        //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
こちらから
こうすると文字のキーを押しても無視されるようになる
 
 
結果
イメージ 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
デバッグからリリースにしてデバッグ開始すると
 

f:id:gogowaten:20191211183942p:plain

なにこれこわい
こんな感じなので使うのを諦めた
 
 
次にPixtack紫陽花2ndのときにはあちこち参考にして、ユーザーコントロールで作ったのがあるけど、手間がかかった割にイマイチなできに終わったのでそれも使いたくなくて、簡単に作る方法ないかなあって探していたのよねえ、そこでStack Overflowで見つかったのがScrollBarを使う方法!
今回は満足なものができたので記事にした次第
 
 
今まではVisualBasicばかりだったけど、今回はC#
バブルソートの記事以来2回目かな
WPFでわからないことをググるVBよりC#のほうが多いからC#のほうがラクかも
VBはエクセルのVBAがあるからWindowsアプリはC#にしようかなあ
 
Numericはヌメリック派です!
nullはヌルなんだからNumericはヌメリックなんだよなあ
でもASUSはアサス派
 
 
関連記事
2018/04/03、これで毎回同じのを作らなくて済むようになったかも
WindowsFormのNumericUpDownみたいなのをWPFのユーザーコントロールでDLLで作ってみた ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15442773.html