在Xamarin.Forms SAP中,具有可绑定属性的自定义视图不能正确地绑定。

4

我是一名有用的助手,可以翻译文本。

我有一个复选框,应该触发按钮的IsEnabled事件。但是某种原因导致命令从未得到正确绑定,因此也没有被执行。

这是CheckBox.xaml.cs(控件)中的可绑定属性:

public static readonly BindableProperty CheckBoxCommandProperty =
       BindableProperty.Create<CheckBox, ICommand>(
       checkbox =>
           checkbox.CheckBoxCommand,
           null,
           propertyChanged: (bindable, oldValue, newValue) =>
               {
                   CheckBox checkbox = (CheckBox)bindable;
                   EventHandler<bool> eventHandler = checkbox.CheckedChanged;
                   if (eventHandler != null)
                   {
                       eventHandler(checkbox, checkbox.IsChecked);
                   }
               });

   public event EventHandler<bool> CheckedChanged;

   public ICommand CheckBoxCommand
   {
       get { return (ICommand)GetValue(CheckBoxCommandProperty); }
       set { SetValue(CheckBoxCommandProperty, value); }
   }

这是我在ViewModel上的内容:

   public ICommand Next_OnClick { get; set; }
   public ICommand OnCheckBoxTapChanged { get; set; }

   public TermsAndConditionsViewModel()
   {
       Next_OnClick = new Command(NextClicked);
       OnCheckBoxTapChanged = new Command(CheckBoxTapped);
   }

   private void CheckBoxTapped()
   {
       if (IsCheckedChanged)
       {
           Next_IsEnabled = true;
       }
       else
       {
           Next_IsEnabled = false;
       }
   }

复选框的点击事件方法CheckBoxTapped从未执行过,因此我想要设置的按钮属性永远不会改变。
感谢大家提前帮忙!

为什么不能将按钮的可见性绑定到一个布尔属性,然后使用转换器将复选框的选中状态绑定到同一属性? - Immons
2个回答

2
你可以把解决此问题的方法分为几个级别:
首先,为复选框创建一个可绑定属性,并将其命名为 IsChecked。我已经为此编写了一段代码片段,但并没有真正编译它,如果不起作用,你可能需要修改它。
  public static readonly BindableProperty IsCheckedProperty = 
    BindableProperty.Create<CheckBox, bool> (w => w.IsChecked, false);

  public bool IsChecked{
    get { return GetValue (FooProperty); }
    set { SetValue (FooProperty, value); } 
  }

其次,在视图模型中创建一个布尔属性,并添加更改通知。
private bool _isChecked;
public bool IsChecked
{
    get 
    { 
        return _isChecked;
    }
    set
    {
        _isChecked = value;
        RaisePropertyChanged("IsChecked");
    }
} 

第三步,将复选框的可绑定属性“isChecked”与视图模型中的属性在xaml中绑定:

<StackLayout>
    <Checkbox IsChecked = "{Binding IsChecked}"/>
</StackLayout>

第四点,使用MVVM的Xaml按钮会被绑定到命令上。这些命令有一个布尔属性,代表“CanExecute”,用于启用或禁用按钮。因此,在Xaml中,您需要将按钮的命令绑定到视图模型中的命令(我们称之为ClickCommand)。而ClickCommand的CanExecute实际上只是一个返回"IsChecked"值的方法。
这将使我们修改“IsChecked”属性的setter,以便每次更改时通知命令检查CanExecute属性。
因此,最终的代码将类似于:
public TermsAndConditionsViewModel()
   {
       NextCommand = new Command(ExecuteNextCommand,CanExecuteNextCommand);
       OnCheckBoxTapChanged = new Command(CheckBoxTapped);
   }


private bool _isChecked;
public bool IsChecked
{
    get { return _isChecked;}
    set
    {
         _isChecked = value;
    NextCommand.ChangeCanExecute(); //this will actually notify the command to enable/disable
        RaisePropertyChanged("IsChecked");
    }
}


public Command NextCommand {get;set;} // this type is available in Xamarin.Forms library
private bool CanExecuteNextCommand()
{
    return IsChecked;
}
private void ExecuteNextCommand()
{
    // your execution when the button is pressed    
}

而Xaml将会是这样的

<StackLayout>
    <Checkbox IsChecked = "{Binding IsChecked}"/>
    <Button Text= "Next" Command = "{Binding NextCommand}"/>
</StackLayout> 

1
使用Xamarin.Forms.Behavior解决了这个问题。它允许将多个绑定应用于控件。
例如>
<Entry Placeholder="Enter password"
             Text= "{Binding TxtFirstPasswordInput}"
             IsPassword="true">
        <b:Interaction.Behaviors>
          <b:BehaviorCollection>
            <b:EventToCommand EventName="Unfocused" Command="{Binding entry_Finished}"/>
            <b:EventToCommand EventName="Focused" Command="{Binding entry_Focused}"/>
          </b:BehaviorCollection>
        </b:Interaction.Behaviors>
      </Entry>

在ViewModel上>
public PasswordInputViewModel()
        {
            entry_Finished = new Command(validateAndContinue);//unfocused
            entry_Focused = new Command(entryFocused); //focused
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接