值转换器在 Xamarin 中不起作用

Value Converter not working in Xamarin

这里有点困惑,我似乎已经遵循了允许我使用值转换器的步骤。

我用密钥定义了我的转换器,因此:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage Title="Article"
                 xmlns="http://xamarin.com/schemas/2014/forms"
                           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:controls="clr-namespace:XamarinMobile.Controls;assembly=XamarinMobile"
                 xmlns:converters="clr-namespace:XamarinMobile.Converters;assembly=XamarinMobile"
                 x:Class="XamarinMobile.ArticlePage">
      <ContentPage.Resources>
        <ResourceDictionary>
          <converters:FontSizeConverter x:Key="FontSizeMapper"></converters:FontSizeConverter>
        </ResourceDictionary>
      </ContentPage.Resources>

然后我在我的 XAML 中使用我的转换器,例如:

          <ContentView Padding="10,-10,10,0" Grid.Row="2" Grid.Column="0">
            <StackLayout>
              <Label x:Name="LabelAuthor" FontSize="{Binding 20, Converter={StaticResource FontSizeMapper}, ConverterParameter=20}" />
              <Label x:Name="LabelPublishDate" FontSize="{Binding 10, Converter={StaticResource FontSizeMapper}, ConverterParameter=10}"/>
            </StackLayout>
          </ContentView>

这是我的实际转换器代码:

namespace XamarinMobile.Converters
{
    public class FontSizeConverter : Xamarin.Forms.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if(value is double)
            {
                return App.NormalizeFontSize((double)value);
            } else
            {
                return value;
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

然后我在我的值转换器中放置了一个断点,但它从未命中。有什么明显的东西我在这里失踪了吗?我很确定我是按照指示去发球台的。

由于 所说,您的断点未被命中。你的绑定坏了。你的绑定说的是:绑定到 BindingContext 上名为“10”的 属性,并使用 Converter FontSizeMapper,将额外的 ConverterParameter 传递给它 10。” 10" 不是有效的 属性 名称,因此绑定中断。如果查看日志,您应该会看到类似于以下内容的消息:"Binding: '10' property not found on ..."

修复它的一种方法是删除您尝试绑定的 "Path" 并仅使用 ConverterParameter(假设您不需要绑定到任何真实的属性):

FontSize="{Binding Converter={StaticResource FontSizeMapper}, ConverterParameter=20}"

请注意,您需要在转换器中使用 parameter,而不是 value(例如 if (parameter is double))。

如果您不需要绑定到任何属性,另一种解决方法是改用自定义标记扩展。

[ContentProperty("FontSize")]
public class FontSizeMapperExtension : IMarkupExtension
{
    public double FontSize { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return App.NormalizeFontSize(FontSize);
    }
}

然后您可以在 XAML 中使用它,例如:

FontSize="{converters:FontSizeMapper FontSize=10}

编辑

绑定到对象上的 属性 的示例:

public class YourViewModel
{
    public double VMFontSize { get; set; }
}

public partial class ArticlePage : ContentPage
{
    public ArticlePage()
    {
        InitializeComponent();

        // NOTE: You'd probably get your view-model another way
        var viewModel = new YourViewModel { VMFontSize = 10 };
        BindingContext = viewModel;
    }
}

现在您的 view-model 已设置为绑定上下文,您可以像这样设置绑定:

FontSize="{Binding VMFontSize, Converter={StaticResource FontSizeMapper}}"

这里说的是:将标签上的FontSize属性绑定到当前BindingContext(你的view-model)上的VMFontSize属性,使用转换器来view-model 的 VMFontSize 和 Label 的 FontSize 之间的映射。我把 ConverterParameter 去掉了,因为在这个例子中它并不是真正需要的,但是如果你需要的话你可以传递一个。

我会以不同的方式执行此操作,使用自定义附加 属性,请在此处查看有关附加属性的更多信息 https://developer.xamarin.com/guides/xamarin-forms/xaml/attached-properties/

这是您的场景示例,首先我们需要定义一个附加的 属性,它可以是任何 class,我叫我的 FontHelper

namespace App23
{
    public static class FontHelper
    {
        public static readonly BindableProperty FontSizeProperty =
            BindableProperty.CreateAttached("FontSize", typeof(double), typeof(FontHelper), 0d, propertyChanging:OnPropertyChanging);

        public static bool GetFontSize(BindableObject view)
        {
            return (bool)view.GetValue(FontSizeProperty);
        }

        public static void SetFontSize(BindableObject view, bool value)
        {
            view.SetValue(FontSizeProperty, value);
        }

        private static void OnPropertyChanging(BindableObject bindable, object oldValue, object newValue)
        {
            if (bindable is Label)
            {
                var label = bindable as Label;
                double fontSize = (double)newValue;
                // normalize your font size here
                label.FontSize = fontSize;
            }
        }
    }
}

然后在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:local="clr-namespace:App23"
             x:Class="App23.MainPage">

  <Label Text="Welcome to Xamarin Forms!"
           VerticalOptions="Center"
           HorizontalOptions="Center" local:FontHelper.FontSize="50"/>

</ContentPage>