如何在Xamarin.Mac中绑定Project对象的Tasks列表到Array Controller
解决Xamarin.Mac中PCL对象绑定Array Controller的问题
核心问题原因
PCL(可移植类库)中的类默认无法被Objective-C运行时识别,因为PCL不包含Xamarin.Mac特有的[Register]/[Expose]特性依赖的程序集,直接添加这些特性会触发编译错误。同时Array Controller依赖Objective-C的KVC/KVO机制,必须使用继承自NSObject、能被ObjC识别的对象才能完成绑定。
具体解决步骤
1. 确保PCL类的基础可访问性
先确认PCL中的Task和Project类为public,且Project的Tasks属性使用支持变更通知的集合类型(比如ObservableCollection<Task>,方便后续UI自动更新):
// PCL中的Project类 public class Project { public ObservableCollection<Task> Tasks { get; set; } = new ObservableCollection<Task>(); // 其他业务属性... } // PCL中的Task类 public class Task { public string Name { get; set; } // 其他业务属性... }
2. 在Mac项目中创建NSObject包装类
在Xamarin.Mac Cocoa项目内,创建继承自NSObject的包装类,包裹PCL的Project对象,同时将需要绑定的属性暴露给Objective-C:
using Foundation; using System.Collections.ObjectModel; using YourPCLNamespace; // 替换为你的PCL实际命名空间 [Register("WrappedProject")] public class WrappedProject : NSObject { private readonly Project _innerProject; public WrappedProject(Project project) { _innerProject = project; // 监听PCL集合变化,触发ObjC的KVO通知,同步更新UI _innerProject.Tasks.CollectionChanged += (_, __) => { WillChangeValue("tasks"); DidChangeValue("tasks"); }; } // 用[Export]特性暴露属性给Objective-C,命名遵循ObjC小驼峰规则 [Export("tasks")] public ObservableCollection<Task> Tasks => _innerProject.Tasks; }
3. 在ViewController中集成包装类
在ViewController里初始化PCL的Project对象,包装成WrappedProject后暴露给绑定系统:
public partial class ViewController : NSViewController { private WrappedProject _wrappedProject; public ViewController(IntPtr handle) : base(handle) { } public override void ViewDidLoad() { base.ViewDidLoad(); // 初始化PCL项目并添加测试数据 var project = new Project(); project.Tasks.Add(new Task { Name = "任务1" }); project.Tasks.Add(new Task { Name = "任务2" }); // 包装为ObjC可识别的对象 _wrappedProject = new WrappedProject(project); } // 暴露包装对象给绑定系统 [Export("project")] public WrappedProject Project => _wrappedProject; }
4. Interface Builder绑定设置
打开Storyboard/XIB,完成以下绑定操作:
- 选中Array Controller,在Bindings Inspector中:
- 绑定
Content Array到ViewController的project.tasks属性
- 绑定
- 选中Table View的列,绑定
Value到Array Controller的arrangedObjects.name(对应Task的Name属性,ObjC命名为小驼峰)
5. 关键注意事项
- 禁止直接在PCL类上添加
[Register]或[Expose]特性,PCL项目无法引用Xamarin.Mac的Foundation程序集,会导致编译失败 - 必须使用
ObservableCollection作为集合类型,配合包装类中的变更监听触发KVO通知,才能实现UI自动更新 - 所有需要绑定的属性都要通过
[Export]特性暴露,且命名需遵循Objective-C的小驼峰规则
内容的提问来源于stack exchange,提问作者Mihai Nejneriu
相关产品推荐
相关产品推荐

