Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
xamarin:Binding命令_Xamarin_Binding_Command - Fatal编程技术网

xamarin:Binding命令

xamarin:Binding命令,xamarin,binding,command,Xamarin,Binding,Command,将命令绑定到按钮-不产生任何效果(Xamarin、MVVM): 注: 按下按钮,无任何反应:无CanExecute检查发生 绑定作为选项卡式模板一部分的ContentPage中的按钮 功能检查和其他相关的MVVM绑定工作良好:定义了一个单击事件,并从代码背后手动触发了命令 //有人知道原因吗?//编辑 编辑,新: 当CanExecute依赖于独立更新的复合数据类型字段时,什么是一个好的实践?(*可以使用命令参数,该参数是复合数据类型,命令可以通过VM直接访问该类型) 视图的xaml:

将命令绑定到按钮-不产生任何效果(Xamarin、MVVM):

注:

  • 按下按钮,无任何反应:无CanExecute检查发生
  • 绑定作为选项卡式模板一部分的ContentPage中的按钮
  • 功能检查和其他相关的MVVM绑定工作良好:定义了一个单击事件,并从代码背后手动触发了命令
//有人知道原因吗?//编辑 编辑,新: 当CanExecute依赖于独立更新的复合数据类型字段时,什么是一个好的实践?(*可以使用命令参数,该参数是复合数据类型,命令可以通过VM直接访问该类型)

视图的xaml:

    <ContentPage.Content>
    <StackLayout>
        <Entry Placeholder="Notes"/>
        <Entry x:Name="courseIDEntry" 
               Text="{Binding CourseID, Mode=TwoWay}"
               IsReadOnly="{Binding !ExistUnit}"
               Placeholder="CourseID *"/>
        <Entry x:Name="unitIDEntry" 
               Text="{Binding UnitID, Mode=TwoWay}"
               IsReadOnly="{Binding !ExistUnit}"
               Placeholder="UnitID *"/>enter code here
        <Label Text="* Fields are mandatory"/>
        <Button x:Name="AddSave"
            Text="{Binding CommandText}" 
            Command="{Binding AddSaveCMD}"    
            CommandParameter="{Binding EdittedUnit}"/>
            <!--Clicked="AddSave_Clicked"/>--> 
    </StackLayout>
</ContentPage.Content>enter code here
C#MyCommand(新手,使用ICommand而不是Command类)

c#用于VM(BaseViewModel实现INotify)

选项卡页的xaml:

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        xmlns:views="clr-namespace:P205.Views"
        x:Class="P205.Views.MyTabbedPage">

<views:UnitsPage Title="Units" />
<views:EditUnitPage x:Name="editOrAddUnit" Title="Edit U"/>
<views:DBChangesPage Title="Edit DB"/>
<views:CoursesPage Title="Course"/> 

<ContentPage Padding="10">
    
</ContentPage>

当ViewModel定义类型为
ICommand
的属性时,ViewModel还必须包含或引用实现
ICommand
接口的类。此类必须包含或引用
Execute
CanExecute
方法,并在
CanExecute
方法可能返回不同值时触发
CanExecuteChanged
事件

因此,您可以尝试以下更改:

public class AddSaveUnitCommand : ICommand
{
   public EditUnitViewModel EditUVM { get; set; }


   public event EventHandler CanExecuteChanged;

   public AddSaveUnitCommand(EditUnitViewModel euvm)
   {
   EditUVM = euvm;
   }

   public bool CanExecute(object parameter)
   {
      var editted = parameter as Unit6;

      if (editted != null )
      {
         if (!string.IsNullOrEmpty(editted.CourseID) || !string.IsNullOrEmpty(editted.UnitID))
            return true;
      }
      return false;
   }

  public void Execute(object parameterf)
  {
     EditUVM.AddSaveUnitAsync();
     CanExecuteChanged?.Invoke(this, EventArgs.Empty); //add this line.
  }
}

非常感谢。1.问题是,代码甚至没有到达CanExcute:在CanExcute上使用断点,我只能在应用程序启动时在视图的InitializeComponent()上看到它。在运行期间和页面本身上-代码没有到达那里。2.正如我所提到的,我已经实现并绑定了其他命令:使用类似的功能注册和登录到应用程序,它们工作得很好。3.我发现的一个不同之处是,我在一个选项卡模板中处理contentPage。是否添加了
CanExecuteChanged?.Invoke(这个,EventArgs.Empty)如上所述?当绑定第一次在按钮的
命令
属性上定义时,当数据绑定以某种方式更改时,按钮在ICommand对象中调用
CanExecute
方法。我还在tabbedpage中测试了它,它可以工作。您好,我已经尝试过了。它没有到达那条线。我一直在寻找,并了解到没有直接绑定到OnPropertyChanged通知属性。1.我将从这里继续:学习在只更新复合数据类型上的字段时引发OnPropertyChanged()的良好实践。2.它与最初怀疑的选项卡式模板无关,因此我将编辑该主题。谢谢。如果可能的话,你可以分享你的项目,我会测试一下。
public class EditUnitViewModel : BaseViewModel
{
    public AddSaveUnitCommand AddSaveCMD { get; set;  }

    private Unit6 edittedUnit;
    public Unit6 EdittedUnit
    {
        get { return edittedUnit; }
        set { edittedUnit = value; OnPropertyChanged(); }
    }

    private bool existUnit;
    public bool ExistUnit
    {
        get { return existUnit; }
        set 
        { 
            existUnit = value;
            //OnPropertyChanged(); 
        }
    }

    public string CommandText
    {
        get { return ExistUnit? "Save": "Add"; }
    }

    public string CourseID
    {
        get { return EdittedUnit.CourseID; }
        set { EdittedUnit.CourseID = value; OnPropertyChanged(); }
    }

    public string UnitID
    {
        get { return EdittedUnit.UnitID; }
        set { EdittedUnit.UnitID = value; OnPropertyChanged(); }
    }

    public EditUnitViewModel()
    {
        EdittedUnit = new Unit6();
        AddSaveCMD = new AddSaveUnitCommand(this);
    }

    public async void AddSaveUnitAsync()
    {
        var curPage = App.Current.MainPage;
        try
        {
            switch (ExistUnit)
            {
                case false: //insert new unit to the DB
                    EdittedUnit.UnitKey = ""; //Todo: look for more elegant of assigning auto value to property
                    Unit6.Insert(EdittedUnit);
                    break;
                case true: //update details on existing unit
                    EdittedUnit.UnitKey = ""; //Todo: look for more elegant of assigning auto value to property
                    Unit6.Update(EdittedUnit);
                    break;
            }
            await curPage.DisplayAlert("Success", "Unit was succesffuly updateded", "OK");
        }
        catch
        {
            await curPage.DisplayAlert("Error", "Unit was not updated", "OK");
        }
        finally
        {
            EdittedUnit = null;
            await curPage.Navigation.PushAsync(new MyTabbedPage());
        } 
    }
}
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        xmlns:views="clr-namespace:P205.Views"
        x:Class="P205.Views.MyTabbedPage">

<views:UnitsPage Title="Units" />
<views:EditUnitPage x:Name="editOrAddUnit" Title="Edit U"/>
<views:DBChangesPage Title="Edit DB"/>
<views:CoursesPage Title="Course"/> 

<ContentPage Padding="10">
    
</ContentPage>
public class AddSaveUnitCommand : ICommand
{
   public EditUnitViewModel EditUVM { get; set; }


   public event EventHandler CanExecuteChanged;

   public AddSaveUnitCommand(EditUnitViewModel euvm)
   {
   EditUVM = euvm;
   }

   public bool CanExecute(object parameter)
   {
      var editted = parameter as Unit6;

      if (editted != null )
      {
         if (!string.IsNullOrEmpty(editted.CourseID) || !string.IsNullOrEmpty(editted.UnitID))
            return true;
      }
      return false;
   }

  public void Execute(object parameterf)
  {
     EditUVM.AddSaveUnitAsync();
     CanExecuteChanged?.Invoke(this, EventArgs.Empty); //add this line.
  }
}