Xamarin.Forms DataBinding не работает - PullRequest
0 голосов
/ 01 июля 2018

Я знаю, что этот вопрос задавался много раз раньше, но каждая ситуация в некотором роде уникальна, скажем так.

Моя среда - Visual Studio 15.7.4, в которой используются все пакеты Nuget (прежде всего Xamarin.Forms), обновленные до последней версии.

Проблема в том, что я создал простое приложение для тестирования привязки, и привязка больше не работает! Я уже создал Android-приложение с Xamarin.Forms некоторое время назад, и все это работало просто отлично. Теперь все привязки работают как «OneTime», устанавливая только один раз в начале и не обновляя в пользовательском интерфейсе (но все же обновляя данные в основной 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
  }
}

AppViewModel.cs

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); }
    }
  }
}

MainPage

<?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>

MainPage.cs

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!!!";
    }
  }
}

BaseBind.cs

 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;
    }
  }
}

Это… простой тест приложения, потому что тот, на котором я работал, отображал и эту проблему.

Очень бы хотелось узнать, что не так .. я или Xamarin framework.

Спасибо всем за внимание и терпение.

Ответы [ 3 ]

0 голосов
/ 01 июля 2018

Я еще не создал / не выполнил тестовый проект с вашим кодом, но, похоже, проблема в вашем классе 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;
    }
  }
}
0 голосов
/ 01 июля 2018

Возможно, по какой-то причине ваш OnPropertyChanged(propertyName); вызывает OnPropertyChanged(null); во время выполнения. Проверьте это в отладчике.

0 голосов
/ 01 июля 2018

Не должен ли ваш обработчик Clicked в MainPage.cs быть определен так: public void Test(object sender, System.EventArgs e) { ... }?

...