【问题标题】:How do I stop a button from executing a bound command in Xamarin.Forms using C#?如何使用 C# 阻止按钮在 Xamarin.Forms 中执行绑定命令?
【发布时间】:2021-07-13 04:54:12
【问题描述】:

我创建了一个在“编辑”和“保存”之间切换的按钮。此按钮与我的 ViewModel 中的“保存命令”有数据绑定。

我想停止执行“保存命令”,直到按钮文本等于“保存”。

我尝试切换Command.CanExceute(false),但这似乎不起作用,“保存命令”总是执行!示例代码发布在下面,也可以在我的GitHub Repositry

中找到

MainPage.xaml

    <ContentPage.BindingContext>
        <App:ClientViewModel/>
    </ContentPage.BindingContext>
    
    <StackLayout>
        <Button x:Name="EditSaveButton"
                Text="Edit"
                Command="{Binding SaveClient}"
                Clicked="EditSaveButton_Clicked"/>
    </StackLayout>

MainPage.xaml.cs

        public MainPage()
        {
            InitializeComponent();
            EditSaveButton.Command.CanExecute(false);
        }

        private void EditSaveButton_Clicked(object sender, EventArgs e)
        {
            if (EditSaveButton.Text == "Edit")
            {
                EditSaveButton.Text = "Save";
                EditSaveButton.Command.CanExecute(true);
            }
            else 
            {
                EditSaveButton.Text = "Edit";
                EditSaveButton.Command.CanExecute(false);
            }
        }

ClientViewModel.cs

    public class ClientViewModel
    {
        public Command SaveClient { get; set; }

        public ClientViewModel()
        {
            SaveClient = new Command( async () => {

                await Application.Current.MainPage.DisplayAlert("Saved", "Client Saved", "OK");
            });
        }
    }

###### 更新######

感谢 Jason 和 Robert Harvey 在这方面的指导。 我已将代码更改为仅使用Command 而不是Clicked,并将按钮的文本属性绑定到我的ViewModel 中的属性。但是,当我执行代码时,按钮文本没有更新?任何想法为什么?

Main.xaml

    <StackLayout>
        <Button x:Name="EditSaveButton"
                Text="{Binding EditSaveButtonText}"
                Command="{Binding SaveClient}"/>
    </StackLayout>

ClientViewModel.cs

 public class ClientViewModel
    {
        public Command SaveClient { get; set; }

        public string EditSaveButtonText { get; set; }

        public ClientViewModel()
        {

            SaveClient = new Command( () => {

                if (EditSaveButtonText == "Edit")
                {
                    EditSaveButtonText = "Save";
                }
                else
                {
                    EditSaveButtonText = "Edit";
                }
            });
        }
    }

【问题讨论】:

  • 不要使用命令和单击,选择一种方法。如果您将按钮 Text 绑定到 VM 属性,则您的 VM 可以确定它所处的状态并采取适当的行动
  • 感谢 Jason,因为我的代码需要执行 ViewModel 中可用的一些逻辑(将记录保存到数据库),我将选择命令选项。但是我提供的代码并不完整,我还需要在视图中执行一些逻辑,例如更新按钮颜色等。
  • 您可以将颜色绑定到 VM 属性并使用 ValueConverter
  • 谢谢杰森,我已经更新了我的问题以包含您的更改,但按钮文本没有更新?任何想法为什么?
  • 你的虚拟机需要实现 INotifyPropertyChanged

标签: c# xamarin xamarin.forms mvvm data-binding


【解决方案1】:

Xamarin 中的命令实现ICommand 接口。

public interface ICommand
{
    public void Execute (Object parameter);

    public bool CanExecute (Object parameter);

    public event EventHandler CanExecuteChanged;
}

如果您将按钮中的命令绑定到实现ICommand 的视图模型,只需将CanExecute 设置为false您应该在视图模型中执行此操作,而不是视图。

将事件绑定到按钮或使用Command不要两者都做。如果您需要更改按钮颜色,请将按钮颜色设置为与视图模型的属性的绑定,以便您可以在那里更改它。

【讨论】:

  • 谢谢罗伯特,我已经更新了我的问题以包含您的更改,但按钮文本没有更新?任何想法为什么?
  • 我不会基于按钮的文本。在您的 ViewModel 中放置一个标志以跟踪它;类似bool _isSaved.
  • 谢谢罗伯特,这是一个非常好的建议。 :) 我去做。正如您很可能知道并由上面的 Jason 指出的那样,我没有实现 INotifyPropertyChanged 接口。
猜你喜欢
  • 2016-06-25
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2013-10-09
  • 2018-07-26
相关资源
最近更新 更多