実現したいこと
WPFのMVVMフレームワークでディスプレイキーボードを実装する。
前提
WPFのMVVMでディスプレイキーボード作成を試みていますが、SendWaitを使用するとなぜかUIのTextBox側ではなく、コードに内容が反映されます。また、なぜかBackSpaceはちゃんとTextBoxに反映されます。何がいけないのでしょうか?
発生している問題・エラーメッセージ
特になし(SendWaitが反映されない)
該当のソースコード
c#
1// MainViewModelです。 2using System.Windows.Forms; 3 4namespace SendWaitTest 5{ 6 public sealed class MainViewModel:ViewModelBase 7 { 8 public MainViewModel() 9 { 10 ACommand = new DelegateCommand<string>(x=> ACommandExecute(x)); 11 BsCommand = new DelegateCommand<string>(x => BsCommandExecute(x)); 12 } 13 14 public DelegateCommand<string> ACommand { get; } 15 16 public DelegateCommand<string> BsCommand { get; } 17 18 private bool isFocus; 19 public bool IsFocus 20 { 21 get=> isFocus; 22 set=>SetProperty(ref isFocus, value); 23 } 24 25 private string dataName; 26 public string DataName 27 { 28 get => dataName; 29 set => SetProperty(ref dataName, value); 30 } 31 32 private void ACommandExecute(string x) 33 { 34 IsFocus = true; 35 SendKeys.SendWait("A"); 36 IsFocus = false; 37 } 38 39 private void BsCommandExecute(string x) 40 { 41 IsFocus = true; 42 SendKeys.SendWait("{BS}"); 43 IsFocus=false; 44 } 45 } 46}
C#
1// View側です。(XAMLコードです。) 2<Window x:Class="SendWaitTest.MainView" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 7 xmlns:local="clr-namespace:SendWaitTest" 8 mc:Ignorable="d" 9 Title="MainView" Height="300" Width="300"> 10 <Grid> 11 <Grid.RowDefinitions> 12 <RowDefinition Height="1*"/> 13 <RowDefinition Height="1*"/> 14 <RowDefinition Height="1*"/> 15 </Grid.RowDefinitions> 16 17 <TextBox Name="Text" Margin="10" Width="250" FontSize="14" Grid.Row="0" HorizontalAlignment="Center" Text="{Binding DataName}"> 18 <TextBox.Style> 19 <Style TargetType="TextBox"> 20 <Style.Triggers> 21 <DataTrigger Binding="{Binding IsFocus}" Value="True"> 22 <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName= Text}"></Setter> 23 </DataTrigger> 24 </Style.Triggers> 25 </Style> 26 </TextBox.Style> 27 </TextBox> 28 29 <Button FontSize="14" Margin="10" Grid.Row="1" Content="A" Command="{Binding ACommand}"></Button> 30 <Button FontSize="14" Margin="10" Grid.Row="2" Content="BackSpace" Command="{Binding BsCommand}"></Button> 31 </Grid> 32</Window>
C#
1// ViewModelBaseです。 2using System.ComponentModel; 3using System.Runtime.CompilerServices; 4 5namespace SendWaitTest 6{ 7 public abstract class ViewModelBase : INotifyPropertyChanged 8 { 9 public event PropertyChangedEventHandler PropertyChanged; 10 11 protected bool SetProperty<T>(ref T field, 12 T value, [CallerMemberName] string propertyName = null) 13 { 14 if (Equals(field, value)) 15 { 16 return false; 17 } 18 19 field = value; 20 var h = this.PropertyChanged; 21 if (h != null) 22 { 23 h(this, new PropertyChangedEventArgs(propertyName)); 24 } 25 26 return true; 27 } 28 } 29}
C#
1//DelegateCommandクラスです。 2using System; 3using System.Windows.Input; 4 5namespace SendWaitTest 6{ 7 public sealed class DelegateCommand<T>:ICommand 8 { 9 public event EventHandler CanExecuteChanged; 10 private readonly Action<T> action; 11 private readonly Func<T,bool> canExcute; 12 13 public DelegateCommand(Action<T> action, Func<T, bool> canExcute = default) 14 { 15 this.action = action; 16 this.canExcute = canExcute; 17 } 18 19 public bool CanExecute(object parameter) 20 { 21 return canExcute?.Invoke((T)parameter) ?? true; 22 } 23 24 public void Execute(object parameter) 25 { 26 action?.Invoke((T)parameter); 27 } 28 29 public void DelegateCanExcute() 30 { 31 CanExecuteChanged?.Invoke(this, EventArgs.Empty); 32 } 33 } 34}
試したこと
補足情報(FW/ツールのバージョンなど)
VisualStudio2022を使用しており、C#のバージョンは7.3です。MVVMのフレームワークは使用していません。
※Teratailの規約をよく理解しておらず、別サイトでも質問してしまっています。
※念のため掲載しておきます。(2023/3/17)
MVVMでWPFを用いてSendWaitを画面に反映する方法
コードがとても見にくいので、それぞれをコードブロックにしてください。
[ヘルプ | 質問する時のヒント](https://teratail.com/help/question-tips#questionTips35)
> SendWaitを使用するとなぜかUIのTextBox側ではなく、コードに内容が反映されます。また、なぜかBackSpaceはちゃんとTextBoxに反映されます。
なんか不思議ですね。
SendWaitできるものはほんの一部で、大体はできないですね...
> WPFのMVVMフレームワークで
「MVVM」が重要なポイントでしょうか?(↓みたいのは避けたい)
private void Button_Click(object sender, RoutedEventArgs e)
{
Text.SelectedText = "A";
Text.CaretIndex = Text.SelectionStart + "A".Length;
}
> ディスプレイキーボードを実装する。
これはあくまでテストであって、本来は「ほかのアプリ」に送信するつもりでしょうか?(いわゆる「ソフトウェアキーボード」・「スクリーンキーボード」といった種類のアプリ)
ありがとうございます、コードはブロックにしました。初心者なもので、不慣れで申し訳ありません。
>SendWaitできるものはほんの一部で、大体はできないですね...
そうなんですね、、WPFだとSendKeyも使用できないですし、結構制約されますね…
>「MVVM」が重要なポイントでしょうか?
本業の方でWinFormをWPFに置き換えるという計画が走ってまして、基本的なコードは全てMVVMで行うとの方針ですので、コードビハインドは使用したくはないです。
>これはあくまでテストであって、本来は「ほかのアプリ」に送信するつもりでしょうか?
おっしゃる通りで、これは質問用のコードで実際は他のアプリに送信することにも使用しようと思っていました。
[MVVMでWPFを用いてSendWaitを画面に反映する方法](http://bbs.wankuma.com/index.cgi?mode=al2&namber=101553)
> teratailでは、マルチポスト※の推奨はしていません。
> やむを得ず複数のサイトに質問を投稿された場合は、質問内容にマルチポストをする理由を書き、他のサイトの投稿へのリンクを貼ってください。 また、解決した際には必ずteratail及びすべての投稿に解決した旨と、どのように解決したかを記載してください。
[ヘルプ|他のサービスにも質問投稿をしたい(してしまった)](https://teratail.com/help#posted-otherservice)
> teratailでは、マルチポスト※の推奨はしていません。
そうだったのですね、追加で情報ありがとうございます。そのように処理するようにします。
回答1件
あなたの回答
tips
プレビュー