Xamarin.Forms数据绑定不起作用

Xamarin.Forms数据绑定不起作用,xamarin,data-binding,xamarin.forms,Xamarin,Data Binding,Xamarin.forms,我知道这个问题以前被问过很多次,但每种情况都有点“独特”,让我们这样说吧 我的环境是Visual Studio 15.7.4,使用更新到最新版本的所有Nuget包(最重要的是Xamarin.Forms) 问题是我创建了一个简单的绑定测试应用程序,绑定不再工作了! 不久前,我已经用Xamarin.Forms创建了一个Android应用程序,一切正常。 现在所有的绑定都像“OneTime”一样工作,只在开始时设置一次,而不在UI中更新(但仍在更新主ViewModel中的数据) 我想知道这是一个普遍的

我知道这个问题以前被问过很多次,但每种情况都有点“独特”,让我们这样说吧

我的环境是Visual Studio 15.7.4,使用更新到最新版本的所有Nuget包(最重要的是Xamarin.Forms)

问题是我创建了一个简单的绑定测试应用程序,绑定不再工作了! 不久前,我已经用Xamarin.Forms创建了一个Android应用程序,一切正常。 现在所有的绑定都像“OneTime”一样工作,只在开始时设置一次,而不在UI中更新(但仍在更新主ViewModel中的数据)

我想知道这是一个普遍的Xamarin问题,还是只是我做错了什么。 我已经尽我所能尝试过了,但没有任何改变

以下是完整的代码(要测试,请创建一个Xamarin.Forms应用程序,并选择“共享项目”;我通常将所有逻辑应用程序代码放在项目的共享部分):

App.cs

namespace App1
{
   public partial class App : Application
   {
    public static AppViewModel ViewModel { get; set; }

    public App ()
    {
        InitializeComponent();

        ViewModel = new AppViewModel();
        MainPage = new MainPage();
    }

    // Other App lifecycle methods
  }
}
namespace App1.ViewModels
{
  public class AppViewModel : BaseBind
  {
    public AppViewModel()
    {
        TestoProva = "---";
        BoolProva = false;
    }

    private string testoProva;
    public String TestoProva
    {
        get { return testoProva; }
        set
        {
            SetProperty(ref testoProva, value);
        }
    }

    private bool boolProva;
    public Boolean BoolProva
    {
        get { return boolProva; }
        set { SetProperty(ref boolProva, value); }
    }
  }
}
namespace App1
{
public partial class MainPage : ContentPage
{
    public static AppViewModel ViewModel => App.ViewModel;

    public MainPage()
    {
        InitializeComponent();
        BindingContext = ViewModel;
    }

    public void Test()
    {
        ViewModel.TestoProva = "TESTO CAMBIATO!!!";
    }
  }
}
 namespace App1.ViewModels
 {
  public class BaseBind
  {
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    protected bool SetProperty<T>(ref T storage, T value,
        [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
  }
}
AppViewModel.cs

namespace App1
{
   public partial class App : Application
   {
    public static AppViewModel ViewModel { get; set; }

    public App ()
    {
        InitializeComponent();

        ViewModel = new AppViewModel();
        MainPage = new MainPage();
    }

    // Other App lifecycle methods
  }
}
namespace App1.ViewModels
{
  public class AppViewModel : BaseBind
  {
    public AppViewModel()
    {
        TestoProva = "---";
        BoolProva = false;
    }

    private string testoProva;
    public String TestoProva
    {
        get { return testoProva; }
        set
        {
            SetProperty(ref testoProva, value);
        }
    }

    private bool boolProva;
    public Boolean BoolProva
    {
        get { return boolProva; }
        set { SetProperty(ref boolProva, value); }
    }
  }
}
namespace App1
{
public partial class MainPage : ContentPage
{
    public static AppViewModel ViewModel => App.ViewModel;

    public MainPage()
    {
        InitializeComponent();
        BindingContext = ViewModel;
    }

    public void Test()
    {
        ViewModel.TestoProva = "TESTO CAMBIATO!!!";
    }
  }
}
 namespace App1.ViewModels
 {
  public class BaseBind
  {
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    protected bool SetProperty<T>(ref T storage, T value,
        [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
  }
}
主页

<?xml version="1.0" encoding="utf-8" ?>
  <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:App1"
         xmlns:vm="clr-namespace:App1.ViewModels"
         x:Class="App1.MainPage">
  <ContentPage.BindingContext>
    <vm:AppViewModel/>
  </ContentPage.BindingContext>
  <StackLayout>
    <Label Text="{Binding TestoProva, Mode=OneWay}"/>
    <Button Text="Test" Clicked="Test"/>
  </StackLayout>
</ContentPage>
BaseBind.cs

namespace App1
{
   public partial class App : Application
   {
    public static AppViewModel ViewModel { get; set; }

    public App ()
    {
        InitializeComponent();

        ViewModel = new AppViewModel();
        MainPage = new MainPage();
    }

    // Other App lifecycle methods
  }
}
namespace App1.ViewModels
{
  public class AppViewModel : BaseBind
  {
    public AppViewModel()
    {
        TestoProva = "---";
        BoolProva = false;
    }

    private string testoProva;
    public String TestoProva
    {
        get { return testoProva; }
        set
        {
            SetProperty(ref testoProva, value);
        }
    }

    private bool boolProva;
    public Boolean BoolProva
    {
        get { return boolProva; }
        set { SetProperty(ref boolProva, value); }
    }
  }
}
namespace App1
{
public partial class MainPage : ContentPage
{
    public static AppViewModel ViewModel => App.ViewModel;

    public MainPage()
    {
        InitializeComponent();
        BindingContext = ViewModel;
    }

    public void Test()
    {
        ViewModel.TestoProva = "TESTO CAMBIATO!!!";
    }
  }
}
 namespace App1.ViewModels
 {
  public class BaseBind
  {
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    protected bool SetProperty<T>(ref T storage, T value,
        [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
  }
}
namespace App1.ViewModels
{
公共类基绑定
{
公共事件属性更改事件处理程序属性更改;
public void OnPropertyChanged([CallerMemberName]字符串propertyName=null)=>
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
受保护的布尔集合属性(参考T存储,T值,
[CallerMemberName]字符串propertyName=null)
{
if(object.Equals(storage,value))返回false;
储存=价值;
OnPropertyChanged(propertyName);
返回true;
}
}
}
这就是它…一个简单的应用程序测试,因为我工作的那一个也是这个问题

我真的很想知道什么是错的…我还是Xamarin框架


感谢大家的关注和耐心。

MainPage.cs中的单击处理程序不应该这样定义吗:
public void Test(object sender,System.EventArgs e){…}

我还没有用你的代码创建/运行一个测试项目,但看起来问题可能出在你的BaseBind类上。虽然添加了必要的事件,但实际上并没有将其标记为实现INotifyPropertyChanged,这是绑定引擎为了连接事件所要查找的

试试这个:

namespace App1.ViewModels
 {
  public class BaseBind : System.ComponentModel.INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    protected bool SetProperty<T>(ref T storage, T value,
        [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
  }
}
namespace App1.ViewModels
{
公共类基绑定:System.ComponentModel.INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
public void OnPropertyChanged([CallerMemberName]字符串propertyName=null)=>
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
受保护的布尔集合属性(参考T存储,T值,
[CallerMemberName]字符串propertyName=null)
{
if(object.Equals(storage,value))返回false;
储存=价值;
OnPropertyChanged(propertyName);
返回true;
}
}
}

可能是因为您的
关于PropertyChanged(propertyName)的原因
调用一个
OnPropertyChanged(null)在运行时。在调试器中检查它。

但它会触发。通过调试,我发现除了UI更新之外,一切都正常!非常感谢。我不记得界面了!我怎么会这么笨。现在它工作得很好。再次感谢。