Xamarin.Forms 没有调用转换器
Xamarin.Forms not Calling the Converter
我希望 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, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
但是,当我 运行 应用程序时,转换器似乎没有被调用(我从 public object Convert
处的断点在执行时没有破坏代码的事实中意识到这一点。我做错了什么?
PS:这是我进入Xamarin.Forms的第二天,所以请多多包涵我的代码
您必须从实施 InotifyPropertyChanged
开始,并在 ViewModel 中使用后场 getter 和 setter 绑定 属性:
1- 创建一个助手 class,它将作为您的 ViewModel 的基础,并将实现触发 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- 为您的 ViewModel 创建一个继承自 BaseViewModel
:
的 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 和 属性 值被更改的代码隐藏(逻辑)之间的 inter-communicate 有必要实施Inotifypropertychanged
界面。
相关链接:
我希望 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, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
但是,当我 运行 应用程序时,转换器似乎没有被调用(我从 public object Convert
处的断点在执行时没有破坏代码的事实中意识到这一点。我做错了什么?
PS:这是我进入Xamarin.Forms的第二天,所以请多多包涵我的代码
您必须从实施 InotifyPropertyChanged
开始,并在 ViewModel 中使用后场 getter 和 setter 绑定 属性:
1- 创建一个助手 class,它将作为您的 ViewModel 的基础,并将实现触发 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- 为您的 ViewModel 创建一个继承自 BaseViewModel
:
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 和 属性 值被更改的代码隐藏(逻辑)之间的 inter-communicate 有必要实施Inotifypropertychanged
界面。
相关链接: