Xamarin.Forms 访问绑定对象数据

Xamarin.Forms access Binding object data

我想制作一个标签,提取绑定物品的名称或其他一些数据。

[Display(Description = "Gimme your goddamm first name will ya")]
public string FirstName { get; set; }

代码:

public class TitleLabel : ContentView
{
  public Label Label { get; } = new Label();
  public TitleLabel()
  {
    //TODO ensure Content is not accessed manually
    Content = Label;
  }
  protected override void OnBindingContextChanged() =>
    Label.Text = GetPropertyTitle();


  string GetPropertyTitle()
  {
    var bcp = BindingContextProperty;

    //pseudo:
    var binding = GetBinding(bcp);
    var obj = binding.Object;
    var propertyName = binding.Path;
    var propertyInfo = obj.GetType().GetTypeInfo().DeclaredMembers
      .SingleOrDefault(m => m.Name == propertyName);
    if (propertyInfo == null)
      throw new InvalidOperationException();

    return propertyInfo.GetCustomAttribute<DisplayAttribute>().Description;
  }
}

XAML:

<my:TitleLabel Text="{Binding FirstName}" />

渲染结果:

<my:TitleLabel Text="Gimme your goddamm first name will ya" />

最好的选择是定义一个值转换器。

namespace SampleFormsApp {
public class DisplayNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
      object parameter, CultureInfo culture)
    {
        if (value == null || targetType != typeof(string))
            return null;

        var propertyName = parameter as string;
        if (propertyName == null)
            return null;

        var propertyInfo = value.GetType().GetTypeInfo().DeclaredMembers
          .SingleOrDefault(m => m.Name == propertyName);
        if (propertyInfo == null)
            return null;

        return propertyInfo.GetCustomAttribute<DisplayAttribute>().Name;
    }

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

然后在 App.xaml 中的全局 ResourceDictionary 中声明它:

<ResourceDictionary>
    <local:DisplayNameConverter x:Key="DisplayNameConverter"/>
</ResourceDictionary>

确保声明命名空间:

xmlns:local="clr-namespace:SampleFormsApp"

然后当你想使用它时,你绑定到包含 属性 的对象,并将 属性 名称作为参数传递:

<Label Text="{Binding ., 
  Converter={StaticResource DisplayNameConverter}, ConverterParameter=FirstName}"/>

如果您在 Convert 方法中抛出异常(如上面的示例),它会使应用程序崩溃。在页面呈现期间,它可能会使用空值调用转换器,因此它至少必须对此具有弹性。

“=15=”混合(“=12=”):“=13=” "=10=" "=15=" 兔子:"=13=" "=11="