Home > Net >  WPF: RadioButton do not raise event when its load
WPF: RadioButton do not raise event when its load

Time:05-05

enter image description here

MainWindow.xaml

<Grid>
    <StackPanel>
        <RadioButton Content="A" GroupName="ASD"
                     Command="{Binding ButtonCommand}"
                     IsChecked="True"/>
        <RadioButton Content="B" GroupName="ASD"
                     Command="{Binding ButtonCommand}"/>
        <RadioButton Content="C" GroupName="ASD"
                     Command="{Binding ButtonCommand}"/>
    </StackPanel>
</Grid>

MainViewModel.cs

public class MainViewModel : BaseViewModel
    {
        private ICommand _buttonCommand;
        public ICommand ButtonCommand { get { return (_buttonCommand ?? new BaseCommand(MyAction)); } }

        public void MyAction()
        {
            Debug.WriteLine("clicked");
        }
    }

BaseCommand.cs

public class BaseCommand : ICommand
    {
        private Action _action;

        public BaseCommand(Action action)
        {
            _action = action;
        }

        public event EventHandler? CanExecuteChanged
        {
            add { CommandManager.RequerySuggested  = value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object? parameter)
        {
            return true;
        }

        public void Execute(object? parameter)
        {
            _action();
        }
    }

When I click the button, call MyAction() and print "clicked", It works right. When the window is loaded, I want its raise event click, call to MyAction() and print "clicked", so I set the first radiobutton IsChecked property = true, but it do not raise event. Why? And how to solve it, thanks.

CodePudding user response:

Events and commands are not the same. RadioButoon has many events to reflect input events or state changes, but can invoke only a single command.

To know the available events visit the API class reference of the class e.g. by moving the cursor on the class name and then pressing "F1": RadioButton.

In your case you must handle the RadioButton.Checked event. Note that this event will be raised during the initialization routine of the RadioButton in order to fetch the local IsChecked value. If you really need wait until the button is loaded in framework terms (which means layout calculations and rendering have completed), you can defer the Checked event using the Dispatcher with a DispatcherPriority.Loaded or directly handle the RadioButton.Loaded event (instead of the Checked event alongside using the Dispatcher):

<RadioButton Content="A"
             GroupName="ASD"
             Checked="RadioButton_Checked"
             Loaded="RadioButton_Loaded"
             IsChecked="True" />
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
  RadioButton radioButton = sender as RadioButton;
  // Handle IsChecked changed
  radionButton.Command.Execute(default);

  // Alternatively, wait until the control has loaded (in case you need to reference layout related properties)
  this.Dispatcher.InvokeAsync(() =>
  {
    radionButton.Command.Execute(default);
  }, DispatcherPriority.Loaded);

  // If this is a one-time operation, unregister the event handler
  radioButton.Checked -= RadioButton_Checked;
}

As mentioned before, if you need the RadioButton to be completely loaded, consider to handle the RadioButton.Loaded event instead of using the Dispatcher.

  •  Tags:  
  • wpf
  • Related