0

I have implement the command Binding on Text Box and implement the command for click action in Button. Initially focus is persists in the Text Box only. My issue is me tried to click the button on view through mouse. In this case my text box lost focus command triggered first that is fine but that the button click command is not invoked. Text Box lost focus event handled the event to traverse.

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.DataContext = new ViewModel();
            InitializeComponent();
            txtServer.Focus();
        }
    }
    public class RelayCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;
        private Action<object> execute;

        private Predicate<object> canExecute;

        private event EventHandler CanExecuteChangedInternal;
        public RelayCommand(Action<object> execute = null, Predicate<object> canExecute=null )
        {
          
            this.execute = execute;
            this.canExecute = canExecute;
        }
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            execute.Invoke(parameter);
        }
    }
    public class ViewModel
    {
        private void ActionRequestedEvent(object param)
        {
            
        }
        private ICommand _ActionCommand;
        public ICommand ActionCommand
        {
            get
            {
                if (_ActionCommand == null)
                    this._ActionCommand = new RelayCommand(param =>
                    {
                        ActionRequestedEvent(param);
                    });
                return _ActionCommand;
            }
            set
            {
                _ActionCommand = value;
            }
        }
    }
     <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBox Width="150" Name="txtServer"  Height="25">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="LostFocus">
                        <i:InvokeCommandAction Command="{Binding ActionCommand}" CommandParameter="DataSetServerLostFocus"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </TextBox>
            <Button Content="..." Width="25" Height="25" Margin="3 0 0 0" Command="{Binding ActionCommand}"/>
        </StackPanel>
EldHasp
  • 6,079
  • 2
  • 9
  • 24
Bala
  • 59
  • 5

1 Answers1

0

Most likely your problem is not an implementation problem, but a problem of the testing method you have chosen.
As I assume, you have set breakpoints and are trying to "catch" a call to the ActionRequestedEvent (object param) method.
When the command is executed for the first time, control is transferred to Debug Studio.
You press "Continue" and the command is not executed a second time.
This is due to the fact that after activating the Studio, your Window loses the user focus and therefore the command for the button is no longer called.

Here is an example of testing - you will see the result of calling the method in the Studio's Output Window.

using System.Diagnostics;
using System.Windows.Input;

namespace LostFocusCommand
{
    public class ViewModel
    {
        private int num;   
        private void ActionRequestedEvent(object param)
        {
            Debug.WriteLine($"{++num}: {param}");
        }
        private ICommand _actionCommand;

        public ICommand ActionCommand => _actionCommand
            ?? (_actionCommand = new RelayCommand(ActionRequestedEvent));
    }
}
    public partial class LostFocusCommandWindow : Window
    {
        public LostFocusCommandWindow()
        {
            InitializeComponent();
        }
    }
<Window x:Class="LostFocusCommand.LostFocusCommandWindow"
        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:LostFocusCommand"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        mc:Ignorable="d"
        Title="LostFocusCommandWindow" Height="450" Width="800"
        FocusManager.FocusedElement="{Binding ElementName=txtServer}">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBox Width="150" x:Name="txtServer"  Height="25">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="LostFocus">
                        <i:InvokeCommandAction Command="{Binding ActionCommand}"
                                               CommandParameter="DataSetServerLostFocus"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </TextBox>
            <Button Content="..." Width="25" Height="25" Margin="3 0 0 0"
                    Command="{Binding ActionCommand}"
                    CommandParameter="Button"/>
        </StackPanel>
    </StackPanel>
</Window>

I also wanted to point out to you the incorrect implementation of ICommand. In some cases, such an implementation may not work correctly.
Use the implementation at this link: BaseInpc, RelayCommand and RelayCommand<T> classes.

EldHasp
  • 6,079
  • 2
  • 9
  • 24