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
.