Как связать XAML contentView с его кодом - PullRequest
0 голосов
/ 29 апреля 2019

У меня есть некоторая логика пользовательского интерфейса, и мне нужно добавить их в коде позади. Чтобы преодолеть дублирование кода, мне нужно использовать свойство и изменить его. Нормальная вещь MVVM. Но когда я пытаюсь сделать это с Codebehind. Я имею в виду, что я связываю XAML со своим кодом, чтобы получить доступ к невидимой функции в нескольких местах Проблема в том, что он не является обязательным, или любая другая проблема видимость не изменилась при запуске действия.

Мой ContentView Xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:customRenderes="clr-namespace:DipsDemoXaml.CustomRenderes;assembly=DipsDemoXaml"
         x:Class="DipsDemoXaml.Views.Page1"
         x:Name="navi">

<StackLayout   BindingContext="{x:Reference Name=navi}">
        <customRenderes:NavigationImageButton Source="MenuSettings"                                                
                                                      x:Name="Button1"                                                        
                                                    Margin="0"                                                       
                                                    IsVisible="{Binding Visibility}"                                                                                                                                                                                                                                                                                                                             
                />

В коде позади

public partial class Page1 : ContentView
{
    private bool _expand;

    private bool _visibility;

    public bool Visibility
    {
        get => _visibility;
        set
        {
            _visibility = value;
            OnPropertyChanged();
        }
    }

    public Page1 ()
    {
        InitializeComponent ();        
    }

    private  void  Button1_OnItemTapped(object sender, EventArgs e)
    {
        if (_expand)
        {
            this.Hide();
        }
        else
        {
            this.Expand();
        }
    }

    private async void Expand()
    {
        _expand = true;
        Button5.Opacity = 1;          
        _visibility = true;
        await Button5.RotateTo(180, 200);
    }

    private async void Hide()
    {
        _expand = false;
        Button5.Opacity = 0.4;
        _visibility = false;
        await Button5.RotateTo(360, 200);
    }
}

Как связать это в формах ксамарина. Является ли моя привязка неправильной или в чем проблема

мой метод защиты свойств

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;

        changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

Позвоните Visibility, а не _visibility или вручную запустите OnPropertyChanged. Но 1-й вариант предпочтительнее. Кстати, я не знаю, какова ваша реализация OnPropertyChanged, но обычно она вызывается с именем вашего свойства, как упоминалось @Maniax, или с использованием оператора nameof, например. OnPropertyChanged(nameof(Visibility))

1 голос
/ 29 апреля 2019

Прежде всего, PropetyChanged принимает аргумент,

 OnPropertyChanged("Visibility");

Полагаю, это должно сработать, но странно помещать код ViewModel в код позади.

Идея MVVM состоит в том, чтобы переместить логику со страницы в ViewModel, что позволяет вам управлять состоянием нескольких страниц в одной и той же модели ViewM практически с, если не с кодом, на странице за XAML.

Таким образом, вы, вероятно, должны создать еще один файл, который назовете ViewModel, и поместить в него свою бизнес-логику.

 <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
     xmlns:customRenderes="clr- 
     namespace:DipsDemoXaml.CustomRenderes;assembly=DipsDemoXaml"
     x:Class="DipsDemoXaml.Views.Page1"
     xmlns:vm="clr-namespace:DipsDemoXaml.ViewModels;assembly=DipsDemoXaml"
     x:Class="DipsDemoXaml.Views.Page1"
     x:Name="navi">

<ContentView.BindingContext>
  <vm:MyViewModel/>
</ContentView.BindingContext>
<StackLayout>
<customRenderes:NavigationImageButton Source="MenuSettings"                                                
                                      x:Name="Button1"                                                        
                                      Margin="0"                                                       
                                      IsVisible="{Binding Visibility}"/>                                                                                                                                                                                                                                                                                                                     

А в MyViewModel.cs:

private bool _visibility;

public bool Visibility
{
    get => _visibility;
    set
    {
        _visibility = value;
        OnPropertyChanged("Visibility");
    }
}

Таким образом, вы можете иметь дело с любым желаемым переплетом и легко использовать их на разных страницах.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...