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

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

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:

<RadioButton x:Name="radioButton1"
             Value="Player1"
             Grid.Row="0"
             Grid.ColumnSpan="2"
             BorderWidth="1"
             VerticalOptions="Center"
             IsChecked="True">
    <RadioButton.Content>
        <MultiBinding StringFormat="{}{0} {1}">
            <Binding Path="Name1"/>
            <Binding Path="Player1.Score"/>
        </MultiBinding>
    </RadioButton.Content>
    <RadioButton.Behaviors>
        <toolkit:EventToCommandBehavior
            EventName="CheckedChanged"
            Command="{Binding ChangeCurrentPlayerCommand}"
            CommandParameter="{Binding Source={x:Reference radioButton1}, Path=IsChecked}"/>
    </RadioButton.Behaviors>
</RadioButton>

C# ViewModel:

[RelayCommand]
void ChangeCurrentPlayer(bool isChecked)
{
    if (isChecked)
    {
        CurrentPlayer = Player1;
    }
    else
    {
        CurrentPlayer = Player2;
    }
}

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

&lt;RadioButton x:Name=&quot;radioButton1&quot;
                     Value=&quot;Player1&quot;
                     Grid.Row=&quot;0&quot;
                     Grid.ColumnSpan=&quot;2&quot;
                     BorderWidth=&quot;1&quot;
                     VerticalOptions=&quot;Center&quot;
                     IsChecked= &quot;True&quot;
                     &gt;
            
            &lt;RadioButton.Content&gt;
                &lt;MultiBinding StringFormat=&quot;{}{0} {1}&quot;&gt;
                    &lt;Binding Path=&quot;Name1&quot;/&gt;
                    &lt;Binding Path=&quot;Player1.Score&quot;/&gt;
                &lt;/MultiBinding&gt;
            &lt;/RadioButton.Content&gt;
            &lt;RadioButton.Behaviors&gt;
                &lt;toolkit:EventToCommandBehavior
                        EventName=&quot;CheckedChanged&quot;
                        Command=&quot;{Binding ChangeCurrentPlayerCommand}&quot;
                        CommandParameter=&quot;{Binding Source={RelativeSource Self}, Path=IsChecked}&quot;
                    /&gt;
            &lt;/RadioButton.Behaviors&gt;
        &lt;/RadioButton&gt;

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

[RelayCommand]
        void ChangeCurrentPlayer()
        {

            if (CurrentPlayer == Player1)
            {
                CurrentPlayer = Player2;
            }
            else
            {
                CurrentPlayer = Player1;
            }

        }

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

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的绑定:

<StackLayout>
    <RadioButton x:Name="radioButton1"
         ...
         VerticalOptions="Center"
         IsChecked="True"
         >
        ...
        <RadioButton.Behaviors>
            <toolkit:EventToCommandBehavior
            EventName="CheckedChanged"
            Command="{Binding ChangeCurrentPlayerCommand}"
            CommandParameter="{Binding Source={x:Reference radioButton1}, Path=IsChecked}"
        />
        </RadioButton.Behaviors>
    </RadioButton>
</StackLayout>

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

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

[RelayCommand]
void ChangeCurrentPlayer(bool isChecked)
{
    var a = isChecked;   
    Console.WriteLine("123");
}

希望它能正常工作。

英文:

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:

&lt;StackLayout&gt;
    &lt;RadioButton x:Name=&quot;radioButton1&quot;
         ...
         VerticalOptions=&quot;Center&quot;
         IsChecked= &quot;True&quot;
         &gt;
        ...
        &lt;RadioButton.Behaviors&gt;
            &lt;toolkit:EventToCommandBehavior
            EventName=&quot;CheckedChanged&quot;
            Command=&quot;{Binding ChangeCurrentPlayerCommand}&quot;
            CommandParameter=&quot;{Binding Source={x:Reference radioButton1}, Path=IsChecked}&quot;
        /&gt;
        &lt;/RadioButton.Behaviors&gt;
    &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:

[RelayCommand]
void ChangeCurrentPlayer(bool isChecked)
{
    var a = isChecked;   
    Console.WriteLine(&quot;123&quot;);
}

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:

确定