MVVMCross绑定 - 如何更改对象的可见性

3

我需要学习如何绑定和更改元素的属性。

我应该通过点击按钮来改变元素的可见性。

我有一个名为Hello.axml的文件,其中包含不同的元素。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<TextView
    android:textSize="16sp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    local:MvxBind="Text Strings[VerificationPhoneText]" />
<TextView
    android:textSize="16sp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    local:MvxBind="Text Variable01" />
<Button
    android:id="@+id/enterButton"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    local:MvxBind="Text Strings[EnterButton]; Click ClickCommand" />
<GestureOverlayView
    android:layout_height="284dp"
    android:layout_width="280dp"
    android:background="#FAFAFA"
    android:layout_marginLeft="40dp"
    android:layout_marginRight="40dp"
    android:layout_marginTop="114dp"
    local:MvxBind="Visibility Visibility(MyProperty)">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World" />
    <ImageView
        android:src="@mipmap/ic_check_circle_black_48dp"
        android:layout_marginLeft="95dp"
        android:layout_marginRight="95dp"
        android:layout_marginTop="103dp" />
</GestureOverlayView>

我已经安装了Visibility插件:

PM> Install-Package MvvmCross.Plugin.Visibility -Version 5.6.3

我修改了HelloViewModel.cs文件:

     using MvvmCross.Core.ViewModels;
     using System.Windows.Input;

namespace My.Project.Core.ViewModels
{
    public class HelloViewModel : BaseViewModel
    {
        private bool _myProperty;

        public bool MyProperty
        {
        get
        {
           return _myProperty;
        }
        set
        {
           _myProperty = value;
           RaisePropertyChanged();
      }
  }

        public ICommand ClickCommand => new MvxCommand(() =>
        {
            MyProperty = !MyProperty;
        });
    }
}

但我仍然有一个问题——所有元素在开始时都是可见的,按钮不起作用。

更新。 我的HelloView.cs

using Android.App;

    namespace My.Project.Droid.Views
{
    [Activity]
    public class HelloView:BaseView
    {
        protected override int LayoutResource => Resource.Layout.HelloView;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
        }
    }
}

请帮助我学习它!


可见性是内置的可绑定属性。 - miechooy
@miechooy 我使用完整的 Xamarin,而不是 Xamarin.Forms。 - NaSt
是的,我也在使用MvvmCross和Xamarin,而不是Xamarin Forms。 - miechooy
2个回答

5
如@c.lamont.dev所说,可见性是由MvvmCross的插件(另一个包)管理的:MvvmCross.Plugin.Visibility,您需要在PCL和每个要使用它的平台中添加它。
即使@miechooy的方法可以工作,但是可以通过首先使用插件提供的Visbiility converters来改进,例如MvxVisibilityValueConverterMvxInvertedVisibilityValueConverter,它们允许我们直接绑定到带有该转换器的ViewModel属性,并在内部将ViewModel属性的值转换为我们平台

你将MyProperty设为了私有属性,应该将其改为公共属性,并在setter方法中触发属性更改事件,以便通知视图MyProperty的变化。我已经更新了我的回答。 - fmaccaroni
是的,我修复了它。但是没有帮助。我再次编辑了帖子。由于某种原因,按钮在这个覆盖层之前。也就是说,我可以看到屏幕、覆盖层上的文本和图像以及按钮。 - NaSt
你正在使用RelativeLayout,但是你没有将你的视图相对于其他视图进行定位。在这里https://www.mkyong.com/android/android-relativelayout-example/中解释了如何使用它。顺便问一下,你能否添加你的...View.cs代码? - fmaccaroni
当我只有屏幕而没有覆盖层时,我使用相对位置。但是,在这种情况下,我不知道如何在简单的覆盖层中使用它。这仅仅是用户的通知。是的,我会添加Views.cs,这是非常标准的。 - NaSt
我不确定您是否想要像问题中那样重叠RelativeLayout的所有元素。但如果不是,您必须为每个元素提供一个ID,然后执行类似于android:layout_below="@id/my_view_on_top_of_this"的操作。对于第一个元素,这不是必需的,因为它将放置在RelativeLayout的左上角,但如果您想要,也可以添加android:layout_alignParentLeft="true" - fmaccaroni
显示剩余2条评论

2

如评论中所述,MvvmCross已经创建了可见性绑定。以下是一个示例:

 <android.support.v7.widget.CardView
            android:layout_margin="5dp"
            style="@style/Widget.CardContent"
            local:MvxBind="Visibility MyProperty, Converter=BooleanToVisibilty"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
</android.support.v7.widget.CardView>

只需在您的视图模型中声明属性即可。
  public bool MyProperty
        {
            get
            {
                return _myProperty;
            }
            set
            {
                _myProperty = value;
                RaisePropertyChanged();
            }
        }

最后创建BooleanToVisibilityConverter:
 public class BooleanToVisibiltyValueConverter : MvxValueConverter<bool, ViewStates>
    {
        protected override ViewStates Convert(bool value, Type targetType, object parameter, CultureInfo culture)
        {
            return value ? ViewStates.Visible : ViewStates.Gone;
        }
    }

2
你确定MvvmCross包含Visibility吗?我认为你需要安装MvvmCross.Plugin.Visibility包。然后你就不需要转换器了,你可以直接使用local:MvxBind="Visibility Visibility(MyProperty) - c.lamont.dev
谢谢您的建议!我能够在没有构建错误的情况下集成这个解决方案。但是我仍然不明白如何通过单击按钮来更改可见性。我已经更改了帖子中的代码。在这种情况下,所有元素都是可见的。 - NaSt

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