值转换器在Xamarin中不工作

值转换器在Xamarin中不工作,xamarin,xamarin.forms,ivalueconverter,Xamarin,Xamarin.forms,Ivalueconverter,这里有点困惑,我似乎遵循了允许我使用值转换器的步骤 我用一个键定义了转换器,如下所示: <?xml version="1.0" encoding="utf-8" ?> <ContentPage Title="Article" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.micros

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

我用一个键定义了转换器,如下所示:

    <?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>
          <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>

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

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

解决此问题的一种方法是删除您试图绑定到的“路径”,并且只使用
ConverterParameter
(假设您不需要绑定到任何实际属性):

请注意,您需要使用转换器中的
参数,而不是
值(例如
如果(参数为双精度)

如果不需要绑定到任何属性,另一种修复方法是使用自定义标记扩展

[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;
    }
}
既然您的视图模型被设置为绑定上下文,您可以像下面这样设置绑定:

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

这说明的是:使用转换器在视图模型的VMFontSize和标签的FontSize之间映射,将标签上的FontSize属性绑定到当前
BindingContext
(视图模型)上的VMFontSize属性。我在这里关闭了
ConverterParameter
,因为在本例中它不是真正需要的,但是如果需要,您可以传递一个。

由于所说的原因,您的断点没有被击中。你的带子坏了。绑定的意思是:绑定到
BindingContext
上名为“10”的属性,并使用
Converter
FontSizeMapper,将额外的
ConverterParameter
传递给它10。“10”不是有效的属性名称,因此绑定正在中断。如果查看日志,您应该会看到类似于“Binding:'10'属性未在上找到…”的消息

解决此问题的一种方法是删除您试图绑定到的“路径”,并且只使用
ConverterParameter
(假设您不需要绑定到任何实际属性):

请注意,您需要使用转换器中的
参数,而不是
值(例如
如果(参数为双精度)

如果不需要绑定到任何属性,另一种修复方法是使用自定义标记扩展

[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;
    }
}
既然您的视图模型被设置为绑定上下文,您可以像下面这样设置绑定:

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

这说明的是:使用转换器在视图模型的VMFontSize和标签的FontSize之间映射,将标签上的FontSize属性绑定到当前
BindingContext
(视图模型)上的VMFontSize属性。我在这里关闭了
ConverterParameter
,因为在本例中它不是真正需要的,但是如果需要,您可以传递一个。

我会用另一种方式,使用自定义的附加属性,请参阅此处有关附加属性的更多信息

这是一个场景示例,首先我们需要定义一个附加属性,它可以在任何类中,我称之为mine 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>

我会用另一种方式,使用自定义的附加属性,请参见此处的附加属性详细信息

这是一个场景示例,首先我们需要定义一个附加属性,它可以在任何类中,我称之为mine 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>


您正在“绑定”一个静态值(使用
binding 20
),我认为您应该在
BindingContext
对象中绑定一个属性如果我理解正确,这就是传递value参数的方式。我想传递不同的值,为每个值创建一个属性似乎效率不高。不,你应该绑定到一个有值的属性,只是在你的情况下,它不是可用作FontSize的值。因此,需要一个转换器将属性中的值转换为FontSize。假设您绑定到一个属性,该属性包含一个字符串大小,如
“twenth”
FontSize
属性无法理解
“二十”
,因此需要使用转换器对其进行转换。绑定到包含字符串值的属性,并通过转换器进行转换。希望它有意义。感谢您的回复,但是当我在XAML中使用它时,如何将它绑定到属性?你是说值必须是字符串吗?我不明白。我完全理解fontsize不理解“二十”,这就是为什么我要传递一个double(实际上是一个整数,但可以被视为double)。我遇到的问题是,它甚至不会进入我的值转换器。我会为此使用附加属性。如果您正在“绑定”到静态值(使用
binding 20
),我认为您应该在
BindingContext
对象中绑定属性如果我理解正确,这就是传递值参数的方式。我想传递不同的值,为每个值创建一个属性似乎效率不高。不,你应该绑定到一个有值的属性,只是在你的情况下,它不是可用作FontSize的值。因此,需要一个转换器将属性中的值转换为FontSize。假设您绑定到一个属性,该属性包含一个字符串大小,如
“二十”