如何将单选按钮的IsChecked属性传递为命令参数。

huangapple go评论112阅读模式
英文:

How to pass radio button IsChecked property as command parameter

问题

You can pass the IsChecked property as a parameter to your command using Xamarin.Forms behaviors. To fix the exception issue, you should make sure that the ChangeCurrentPlayer method has the correct signature to accept a boolean parameter. Here's how you can modify your XAML and method:

XAML:

  1. <RadioButton x:Name="radioButton1"
  2. Value="Player1"
  3. Grid.Row="0"
  4. Grid.ColumnSpan="2"
  5. BorderWidth="1"
  6. VerticalOptions="Center"
  7. IsChecked="True">
  8. <RadioButton.Content>
  9. <MultiBinding StringFormat="{}{0} {1}">
  10. <Binding Path="Name1"/>
  11. <Binding Path="Player1.Score"/>
  12. </MultiBinding>
  13. </RadioButton.Content>
  14. <RadioButton.Behaviors>
  15. <toolkit:EventToCommandBehavior
  16. EventName="CheckedChanged"
  17. Command="{Binding ChangeCurrentPlayerCommand}"
  18. CommandParameter="{Binding Source={x:Reference radioButton1}, Path=IsChecked}"/>
  19. </RadioButton.Behaviors>
  20. </RadioButton>

C# ViewModel:

  1. [RelayCommand]
  2. void ChangeCurrentPlayer(bool isChecked)
  3. {
  4. if (isChecked)
  5. {
  6. CurrentPlayer = Player1;
  7. }
  8. else
  9. {
  10. CurrentPlayer = Player2;
  11. }
  12. }

By using {Binding Source={x:Reference radioButton1}, Path=IsChecked}, you pass the IsChecked property of the specific radioButton1 instance as a parameter to your ChangeCurrentPlayer command. This should help you determine which button is currently calling the command without encountering the "Operation is not valid" exception.

英文:

Right now I have a xaml page in MAUI .Net with the following radio button

  1. &lt;RadioButton x:Name=&quot;radioButton1&quot;
  2. Value=&quot;Player1&quot;
  3. Grid.Row=&quot;0&quot;
  4. Grid.ColumnSpan=&quot;2&quot;
  5. BorderWidth=&quot;1&quot;
  6. VerticalOptions=&quot;Center&quot;
  7. IsChecked= &quot;True&quot;
  8. &gt;
  9. &lt;RadioButton.Content&gt;
  10. &lt;MultiBinding StringFormat=&quot;{}{0} {1}&quot;&gt;
  11. &lt;Binding Path=&quot;Name1&quot;/&gt;
  12. &lt;Binding Path=&quot;Player1.Score&quot;/&gt;
  13. &lt;/MultiBinding&gt;
  14. &lt;/RadioButton.Content&gt;
  15. &lt;RadioButton.Behaviors&gt;
  16. &lt;toolkit:EventToCommandBehavior
  17. EventName=&quot;CheckedChanged&quot;
  18. Command=&quot;{Binding ChangeCurrentPlayerCommand}&quot;
  19. CommandParameter=&quot;{Binding Source={RelativeSource Self}, Path=IsChecked}&quot;
  20. /&gt;
  21. &lt;/RadioButton.Behaviors&gt;
  22. &lt;/RadioButton&gt;

And I the command is the following method on my ViewModel.

  1. [RelayCommand]
  2. void ChangeCurrentPlayer()
  3. {
  4. if (CurrentPlayer == Player1)
  5. {
  6. CurrentPlayer = Player2;
  7. }
  8. else
  9. {
  10. CurrentPlayer = Player1;
  11. }
  12. }

I want to pass the IsChecked property of the button as a parameter to the command, but the application throws an exception of type:

  1. System.InvalidOperationException: &#39;Operation is not valid due to the current state of the object.&#39;

Is there any way I can do this?
The reason I need to pass that state as an argument is to get around the fact that whenever a radio button is clicked the command is fired twice in a row, making it useless, unless I have a way to know which button is currently calling it.

答案1

得分: 0

行为没有唯一的可视树父级,因此我们无法在其上使用RelativeSource绑定。请参考此问题:Relativesource bindings and behaviors

作为一种解决方法,您可以尝试以下方法。

在XAML中,更改CommandParameter的绑定:

  1. <StackLayout>
  2. <RadioButton x:Name="radioButton1"
  3. ...
  4. VerticalOptions="Center"
  5. IsChecked="True"
  6. >
  7. ...
  8. <RadioButton.Behaviors>
  9. <toolkit:EventToCommandBehavior
  10. EventName="CheckedChanged"
  11. Command="{Binding ChangeCurrentPlayerCommand}"
  12. CommandParameter="{Binding Source={x:Reference radioButton1}, Path=IsChecked}"
  13. />
  14. </RadioButton.Behaviors>
  15. </RadioButton>
  16. </StackLayout>

这将CommandParameter绑定到radiobutton1的IsChecked属性。

在viewModel中,传递正确的参数(IsChecked是bool类型),像这样:

  1. [RelayCommand]
  2. void ChangeCurrentPlayer(bool isChecked)
  3. {
  4. var a = isChecked;
  5. Console.WriteLine("123");
  6. }

希望它能正常工作。

英文:

Behaviours don't have unique visual tree parents so we cannot use RelativeSource binding on it. Please refer to this issue: Relativesource bindings and behaviors.

As a workaround, you could try the following method.

in xaml, change the Binding for CommandParameter:

  1. &lt;StackLayout&gt;
  2. &lt;RadioButton x:Name=&quot;radioButton1&quot;
  3. ...
  4. VerticalOptions=&quot;Center&quot;
  5. IsChecked= &quot;True&quot;
  6. &gt;
  7. ...
  8. &lt;RadioButton.Behaviors&gt;
  9. &lt;toolkit:EventToCommandBehavior
  10. EventName=&quot;CheckedChanged&quot;
  11. Command=&quot;{Binding ChangeCurrentPlayerCommand}&quot;
  12. CommandParameter=&quot;{Binding Source={x:Reference radioButton1}, Path=IsChecked}&quot;
  13. /&gt;
  14. &lt;/RadioButton.Behaviors&gt;
  15. &lt;/RadioButton&gt;

This binds the CommandParameter to the IsChecked Property of this radiobutton1.

And in viewModel, pass the correct parameter (IsChecked is bool type), like this:

  1. [RelayCommand]
  2. void ChangeCurrentPlayer(bool isChecked)
  3. {
  4. var a = isChecked;
  5. Console.WriteLine(&quot;123&quot;);
  6. }

Hope it works.

huangapple
  • 本文由 发表于 2023年5月15日 07:56:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76250155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定