C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: MVVMでWPFを用いてSendWaitを画面に反映する方法


(過去ログ 177 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■101553 / inTopicNo.1)  MVVMでWPFを用いてSendWaitを画面に反映する方法
  
□投稿者/ ky6140 (1回)-(2023/03/14(Tue) 21:27:34)

分類:[C#] 

VisualStudio2022で、C#バージョンは7.3です。

WPFでディスプレイキーボードを作成しようとしているのですが、ViewModel側でSendWaitを送ってもUI側に反映されず、なぜかコード上に追加されます。
更に、なぜかBackSpaceだけ反映され、1文字削除はできます。

何が間違っているのでしょうか?
特にMVVMのフレームワークは使用しておらず、自作のViewModelBaseとDelegateCommandクラスを作って使用しています。

以下、View側のコードです。
<Window x:Class="SendWaitTest.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SendWaitTest"
        mc:Ignorable="d"
        Title="MainView" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <TextBox Name="Text" Margin="10" Width="250" FontSize="14" Grid.Row="0" HorizontalAlignment="Center" Text="{Binding DataName}">
            <TextBox.Style>
            <Style TargetType="TextBox">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsFocus}" Value="True">
                        <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName= Text}"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
        </TextBox>

        <Button FontSize="14" Margin="10" Grid.Row="1" Content="A" Command="{Binding ACommand}"></Button>
        <Button FontSize="14" Margin="10" Grid.Row="2" Content="BackSpace" Command="{Binding BsCommand}"></Button>
    </Grid>
</Window>

以下、ViewModel側のコードです。
public sealed class MainViewModel:ViewModelBase
    {
        public MainViewModel()
        {
            ACommand = new DelegateCommand<string>(x=> ACommandExecute(x));
            BsCommand = new DelegateCommand<string>(x => BsCommandExecute(x));
        }

        public DelegateCommand<string> ACommand { get; }

        public DelegateCommand<string> BsCommand { get; }

        private bool isFocus;
        public bool IsFocus
        {
            get=> isFocus;
            set=>SetProperty(ref isFocus, value);
        }

        private string dataName;
        public string DataName
        {
            get => dataName;
            set => SetProperty(ref dataName, value);
        }

        private void ACommandExecute(string x)
        {
            IsFocus = true;
            SendKeys.SendWait("A");
            IsFocus = false;
        }

        private void BsCommandExecute(string x)
        {
            IsFocus = true;
            SendKeys.SendWait("{BS}");
            IsFocus=false;
        }
    }

以下、ViewModelBaseのコードです。
   public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected bool SetProperty<T>(ref T field,
            T value, [CallerMemberName] string propertyName = null)
        {
            if (Equals(field, value))
            {
                return false;
            }

            field = value;
            var h = this.PropertyChanged;
            if (h != null)
            {
                h(this, new PropertyChangedEventArgs(propertyName));
            }

            return true;
        }
    }

以下、DelegateCommandクラスのコードです。
   public sealed class DelegateCommand<T>:ICommand
    {
        public event EventHandler CanExecuteChanged;
        private readonly Action<T> action;
        private readonly Func<T,bool> canExcute;

        public DelegateCommand(Action<T> action, Func<T, bool> canExcute = default)
        {
            this.action = action;
            this.canExcute = canExcute;
        }

        public bool CanExecute(object parameter)
        {
            return canExcute?.Invoke((T)parameter) ?? true;
        }

        public void Execute(object parameter)
        {
            action?.Invoke((T)parameter);
        }

        public void DelegateCanExcute()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }
    }

引用返信 編集キー/
■101581 / inTopicNo.2)  Re[1]: MVVMでWPFを用いてSendWaitを画面に反映する方法
□投稿者/ ky6140 (2回)-(2023/03/17(Fri) 06:41:33)
https://teratail.com/questions/0pelmw9lnpqil6

別サイトでも質問をしており、そちらで解決致しました。
解決済み
引用返信 編集キー/
■101582 / inTopicNo.3)  Re[2]: MVVMでWPFを用いてSendWaitを画面に反映する方法
□投稿者/ ky6140 (3回)-(2023/03/17(Fri) 06:48:59)
No101581 (ky6140 さん) に返信
> https://teratail.com/questions/0pelmw9lnpqil6
>
> 別サイトでも質問をしており、そちらで解決致しました。

詳しくは別サイトを見て頂きたいですが、SendWait()を別スレッドで動作させると問題なく動作しました。
原因はわかりませんが、クリックイベントからしっかり抜けることが大事なのかもしれません。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -