【问题标题】:Bind Entry TextChanged to the CanExecute method of button command in Xamarin.Forms将条目 TextChanged 绑定到 Xamarin.Forms 中按钮命令的 CanExecute 方法
【发布时间】:2017-11-06 06:55:57
【问题描述】:

如果三个条目中的任何一个为空,我想禁用发送按钮,但如何以 MVVM 方式实现?

我想到了 CanExecute 委托,但如何在 TextChanged 触发时触发它?

另外,如果我选择了行为,如果我使用Behavior<Entry>,我如何与按钮等其他控件进行通信

这是视图:

<ContentPage.Content>
    <AbsoluteLayout>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="56"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="10"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>
            <Label Text="Contact Us" FontSize="Medium" Grid.ColumnSpan="3"/>
            <Entry Text="{Binding ContactData.message_name}" x:Name="subject" Grid.Row="2" Grid.Column="1" Placeholder="Subject"/>
            <Entry Keyboard="Email" Text="{Binding ContactData.receiver_email}" x:Name="email" Grid.Row="3" Grid.Column="1" Placeholder="Email"/>
            <Editor Text="{Binding ContactData.message_subject}" x:Name="body" Grid.Row="4" Grid.Column="1" />

            <Button Grid.Row="5" Grid.Column="1" Command="{Binding ContactFormSent}" Text="Send"/>
        </Grid>
    </AbsoluteLayout>
</ContentPage.Content>

在 ViewModel 中:

public ContactViewModel()
{
    ContactFormSent = new RelayCommand(SendContactInfo);
    ContactData = new ContactModel();
}

private bool CanSend() //this only get called when the view model is constructed
{
    return !(string.IsNullOrWhiteSpace(ContactData.receiver_email) && string.IsNullOrWhiteSpace(ContactData.message_subject) &&
        string.IsNullOrWhiteSpace(ContactData.message_name));
}

在“行为”选项中,我希望它与EntryEditor 一起使用,所以我的方法是Behavior 类,而不是通用版本?如果是这样,那我该如何实现呢?

【问题讨论】:

  • 您能在 OnTextChanged 事件中为所有条目调用 CanSend() 吗?
  • 您可以在视图模型中添加一个布尔值并将按钮的 IsEnabled 属性绑定到该布尔值并从 CanSend() 更新它

标签: c# xamarin mvvm xamarin.forms


【解决方案1】:

通常,为了使用 MVVM 模式对视图事件做出反应,建议您使用EventToCommandBehaviour

但在这种情况下不需要,因为绑定到Entry 的属性的设置器应该在每次文本更改时触发。您可以使用它来触发ChangeCanExecute() on 命令以通知视图现在可以启用/禁用该按钮。

例如:

string _firstName;
public string FirstName
{
    get { return _firstName; }
    set
    {
        if (_firstName != value)
            SendCommand.ChangeCanExecute();
        SetProperty(ref _firstName, value, nameof(FirstName));
    }
}

string _lastName;
public string LastName
{
    get { return _lastName; }
    set
    {
        if (_lastName != value)
            SendCommand.ChangeCanExecute();
        SetProperty(ref _lastName, value, nameof(LastName));
    }
}

string _email;
public string Email
{
    get { return _email; }
    set
    {
        if (_email != value)
            SendCommand.ChangeCanExecute();
        SetProperty(ref _email, value, nameof(Email));
    }
}

Command _sendCommand;
public Command SendCommand 
{
    get
    {
        return _sendCommand ?? (_sendCommand = new Command(OnSend, CanSend));
    }    
}

bool CanSend(object obj)
{
    return Validate();
}

void OnSend(object obj)
{
    if(Validate())
    {
        //actual button click execution
    }
}

bool Validate()
{
    // disable button if any entry empty
    return !string.IsNullOrEmpty(_firstName)
                  && !string.IsNullOrEmpty(_lastName)
                  && !string.IsNullOrEmpty(_email);
}

【讨论】:

    【解决方案2】:

    Command 有一个公共方法ChangeCanExecute()。 当您新建Command 时,您可以指定canExecute 条件。一旦你的TextChanged 事件被触发,调用ChangeCanExecute() 方法。

    例子:

    Command someCommand = new Command(
     () => SomeMethod(),
     ()=> { return CanSend(); }
    );
    

    一旦Button 更改了文本:

    private void TextChanged(object sender, TextChangedEventArgs e)
    {
        ViewModel.someCommand.ChangeCanExecute();
    }
    

    【讨论】:

      猜你喜欢
      • 2016-06-25
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      相关资源
      最近更新 更多