是否可以将 NSTableView 的选择绑定到另一个 tableview 的选择?
比方说,我在核心数据的模型文件中有 2 个实体,其中一个是由X公司。除其他属性外,“交易”实体还具有“DATE”属性和一对一关系“COMPANY”(指定与 X 公司进行特定交易的公司)。另一个实体:“公司”当然包含与X公司进行交易的所有公司的信息。 “公司”实体具有一对多关系“交易”,它是与“交易”实体的“公司”关系相反的关系。
因此,在 IB 中,我创建了一个 NSTableView(带有其自己的 NSArrayController),显示特定日期的所有交易(在 NSPredicate 的帮助下) 。
然后,我创建另一个表视图,显示第一个表视图中所选交易的公司的一对多关系“交易”(显示特定日期的交易)。第二个表视图的 NSArrayController
绑定如下:
** 绑定到:“第一个表视图控制器的名称”,控制器键:选择,模型键路径:COMPANY.TRANSACTIONS(其中的对多关系) “公司”实体)**
到目前为止,一切工作正常,第二个表视图显示 X 公司与第一个表视图中所选交易的公司完成的所有交易。
但我有一组文本字段显示特定交易的详细信息。将这些文本字段与第一个表视图(显示特定日期的交易的视图)的控制器绑定非常简单。 但我想做的是: 1/ 在第一个表视图中查找特定日期的交易,选择其中任意一个 2/ 然后,从第二个表视图中检查该交易的公司(在第一个表视图中选择的)之前的所有交易 3/ 选择任何以前的交易并从该组文本字段中检查交易的详细信息
因此,我自然应该将文本字段的 gp 绑定到第二个表视图的控制器。但我发现第二个表视图中的默认选定行(显示公司之前所有交易的行)不是我在第一个表视图中为特定日期选择的交易。当然,我可以再次在第二个表视图中手动选择该事务...
所以我只想知道是否可以让第二个表视图根据我在第一个表中选择的事务自动选择事务查看绑定?
经过几个小时的谷歌搜索,我通过实现 tableview Delegate 协议解决了问题:
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
if (["nameOf1stTableView" selectedRow] > -1) {
NSArray *objsArray = ["nameOf2ndTableView'sController" arrangedObjects];
for (id obj in objsArray) {
if ([[obj valueForKey:@"DATE"] isEqualToDate: ["nameOf1stTableView'sController".selection valueForKey:@"DATE"]]) {
["nameOf2ndTableView" selectRowIndexes:[NSIndexSet indexSetWithIndex:[objsArray indexOfObject:obj]] byExtendingSelection:NO];
}
}
}
}
但是,这看起来太麻烦了......可以单独通过绑定来完成吗?
Let'say, I've 2 entities in the Core Data's Model file, one being all "transactions" ever done by X company. The "transactions" entity has among other properties, a "DATE" property and a to-one relationship "COMPANY"(specifying the company with which X company has done that particular transaction). The other entity:"companies" of course contains all the companies' info ,with which X company has done transaction. The "companies" entity has a to-many relationships "TRANSACTIONS" which is an inverse relationship to "transactions" entity's "COMPANY" relationship.
So within IB, I created a NSTableView
(with its own NSArrayController
) showing all the transactions on a particular Date (with the help of NSPredicate
).
Then I create another table view showing the to-many relationship "TRANSACTIONS" of the company of the selected transaction in the first table view(which shows transactions on a particular date). The 2nd table view's NSArrayController
binding is like this:
** bind to: "name of the first tableview's controller", Controller Key: selection, Model Key Path:COMPANY.TRANSACTIONS(the to-many relationship in the "companies" entity)**
Everythings work fine up to this moment, the 2nd tableview shows all the transactions X company has done with the company of the selected transactions in the 1st table view.
But I have a group of textfields showing details of a particular transactions. Binding the these textfields with the controller of the 1st table view(the one showing transactions on a particular date) is pretty straightforward.
But what I want to do are:
1/ Look up the transactions on a particular date in the first table view, select any one of them
2/ Then, check all previous transactions of the company of that transaction( selected in the first table view) from the 2nd table view
3/ Select any previous transactions and check the details of the transaction from that group of textfields
So naturally I should have bind the textfields' gp to the 2nd table view's controller. But I found the default selected row in the 2nd table view(the one show all previous transactions of a company) wasn't the transaction I've selected in the 1st tableView for a particular date. Of course, i can manually select that transaction in the 2nd table view again....
So I just want to know if it's possible to have the 2nd table view automatically select the transaction according to the transaction I've selected in the 1st table view thr binding??
After hours of googling, I solved the problem by implementing the tableview Delegate protocol:
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
if (["nameOf1stTableView" selectedRow] > -1) {
NSArray *objsArray = ["nameOf2ndTableView'sController" arrangedObjects];
for (id obj in objsArray) {
if ([[obj valueForKey:@"DATE"] isEqualToDate: ["nameOf1stTableView'sController".selection valueForKey:@"DATE"]]) {
["nameOf2ndTableView" selectRowIndexes:[NSIndexSet indexSetWithIndex:[objsArray indexOfObject:obj]] byExtendingSelection:NO];
}
}
}
}
But,this just look too cumbersome... can it be done with binding alone?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将瞬态属性
dateFilterPredicate
添加到Transaction
模型对象,该对象提供一个选择相关事务的谓词 - 当实例时您希望在表视图 #2 中显示的事务在表视图 #1 中选择 >Transaction
。您需要为交易日期实现一个自定义设置器,以便在对象的交易日期更改时更新谓词。您还需要在
awakeFromFetch
中设置它(它不会调用setTransactionDate
)。然后将数组控制器 2 的过滤谓词绑定到数组控制器 1 的
selection
,但使用dateFilterPredicate
,而不是company.transactions
。Add a transient property
dateFilterPredicate
to theTransaction
model object which provides a predicate which selects the related transactions – the ones you want displayed in table view #2 when that instance ofTransaction
is selected in table view #1.You'll need to implement a custom setter for transaction date in order to update the predicate when the object's transaction date changes. You also need to set it in
awakeFromFetch
(which doesn't callsetTransactionDate
).Then bind array controller 2's filter predicate binding to array controller 1's
selection
, but instead ofcompany.transactions
, usedateFilterPredicate
.