Xamarin.Forms不调用转换器

问题描述

我希望Xamarin.Forms应用程序中的Label元素占据高度的15%。因此,我suggested使用转换器。以下是我使用的代码
我的.xaml文件

<?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:converters="clr-namespace:ConverterClasses"
             x:Class="App_for_e_Toilets.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:DeviceProperties x:Key="DeviceProperties" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <Label
            BackgroundColor="Green" 
            HeightRequest="{Binding DeviceHeight,Converter={StaticResource DeviceProperties}}"
            HorizontalOptions="FillAndExpand"
            HorizontalTextAlignment="Center"
            Text="Welcome"   
            TextColor="White"
            FontAttributes="Bold"
            VerticalTextAlignment="Center"/>
    </StackLayout>

</ContentPage>

我的.xaml.cs文件

using System;
using System.Globalization;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace App_for_e_Toilets
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            BindingContext = this;
            InitializeComponent();
        }
        public double DeviceHeight = Devicedisplay.MaindisplayInfo.Height;
    }
}

namespace ConverterClasses
{
    public partial class DeviceProperties : IValueConverter
    {
        public object Convert(object value,Type targettype,object parameter,CultureInfo culture)
        {
            double retVal = 0.50 * (double)value;
            return retVal;
        }

        public object ConvertBack(object value,CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

但是,当我运行该App时,似乎未在调用该转换器(我从public object Convert处的断点在执行时未破坏代码这一事实中意识到这一点。我在做什么错?

PS:这是我进入Xamarin.Forms的第二天,所以请忍受我的代码

解决方法

您必须首先实现InotifyPropertyChanged,并在ViewModel中使用backfield getter和setter来创建binded属性:

1-创建一个帮助程序类,它将作为ViewModels的基础,并将实现触发InotifyPropertyChanged事件的方法:

BaseViewModel.cs

public abstract class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void SetProperty<T>(ref T field,T value,[CallerMemberName] string name = null)
    {
        if (!Equals(field,value))
            OnPropertyChanged(name);
    }

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

}

2-为从BaseViewModel继承的ViewModel创建clss:

MainPageViewModel.cs

public class MainPageViewModel : BaseViewModel
{
private double labelheight;
public double LabelHeight
   {
     get => labelheight;
     set => SetProperty(ref labelheight,value);
   }
}

LabelHeight将存储标签的高度。

由于您需要设备高度的百分比,因此可以将DeviceDisplay.MainDisplayInfo.Height移动到转换器:

public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
{
    return 0.15 * DeviceDisplay.MainDisplayInfo.Height;
}
HeightRequest="{Binding LabelHeight,Converter={StaticResource DeviceProperties}}"

3-最后将您的BindingContext设置为ViewModel:

public MainPage()
{
    BindingContext = new MainPageViewModel();
    InitializeComponent();
}

绑定与properties一起使用,而不是变量,还可以在ui和更改属性值的代码(逻辑)之间进行相互通信,因此有必要实现Inotifypropertychanged接口。

相关链接:

MVVM Pattern

How to implement INotifyPropertyChanged in Xamarin.Forms

Inotifypropertychanged

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...