Merge pull request #3203 from daboe01/fixed-treeviewbindings

fixed: treeview binding issues
This commit is contained in:
daboe01
2026-03-15 08:58:21 +01:00
committed by GitHub
2 changed files with 42 additions and 53 deletions
+25 -47
View File
@@ -2413,7 +2413,7 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted)
- (void)setValueFor:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath =[_info objectForKey:CPObservedKeyPathKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
value = [destination valueForKeyPath:keyPath];
if (!value || ![value isKindOfClass:[CPTreeNode class]])
@@ -2421,19 +2421,10 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted)
else
_rootNode = value;
// Because CPBinder triggers setValueFor: synchronously during its initialization
// (before -bind is ever called), we must lazily assign the data source here.
if ([_source dataSource] !== self)
{
// Assigning the data source automatically triggers [_source reloadData]
// inside CPOutlineView, so we don't need to call it manually here.
[_source setDataSource:self];
}
else
{
// If it was already set, we just manually trigger the reload.
[_source reloadData];
}
}
- (CPTreeNode)rootNode
@@ -2463,10 +2454,31 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted)
- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
if ([item respondsToSelector:@selector(representedObject)])
return [item representedObject];
var rep = [item respondsToSelector:@selector(representedObject)] ? [item representedObject] : item;
// Dynamically fetch the value using the column's identifier (e.g., "name")
if (rep && [tableColumn identifier] && [tableColumn identifier] !== @"")
return [rep valueForKey:[tableColumn identifier]];
return rep;
}
- (void)outlineView:(CPOutlineView)outlineView setObjectValue:(id)value forTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
var rep = [item respondsToSelector:@selector(representedObject)] ?[item representedObject] : item;
// Push the inline edit back to the model using the column's identifier
if (rep && [tableColumn identifier] && [tableColumn identifier] !== @"")
[rep setValue:value forKey:[tableColumn identifier]];
}
- (id)content
{
// CPTableView internals probe the binder for its flat content to draw rows.
if (_source && _source._itemsForRows)
return _source._itemsForRows;
return item;
return [];
}
@end
@@ -2566,37 +2578,3 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted)
@end
@implementation _CPOutlineViewContentBinder (DynamicColumns)
- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
var rep = [item respondsToSelector:@selector(representedObject)] ? [item representedObject] : item;
// Dynamically fetch the value using the column's identifier (e.g., "name")
if (rep && [tableColumn identifier])
return [rep valueForKey:[tableColumn identifier]];
return rep;
}
// Add this to support inline bidirectional editing in the outline view
- (void)outlineView:(CPOutlineView)outlineView setObjectValue:(id)value forTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
var rep = [item respondsToSelector:@selector(representedObject)] ?[item representedObject] : item;
// Push the inline edit back to the model using the column's identifier
if (rep && [tableColumn identifier])
[rep setValue:value forKey:[tableColumn identifier]];
}
- (id)content
{
// CPTableView internals probe the binder for its flat content to draw rows.
// For an outline view, the flat content is exactly the internally mapped items for rows.
if (_source && _source._itemsForRows)
return _source._itemsForRows;
return [];
}
@end
+17 -6
View File
@@ -3627,17 +3627,28 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
- (void)_setObjectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(CPView)aDataView useCache:(BOOL)useCache
{
var providedByDataSource = NO;
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_)
[aDataView setObjectValue:[self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache]];
{
var objectValue = [self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache];
[aDataView setObjectValue:objectValue];
providedByDataSource = YES;
}
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
// It will override the value set above if there is an explicit column binding.
var columnHasBindings = [[[CPBinder allBindingsForObject:aTableColumn] allKeys] count] > 0;
if (_contentBindingExplicitlySet)
[self _prepareContentBindedDataView:aDataView forRow:aRow];
else
// For both cell-based and view-based
if (columnHasBindings)
{
[aTableColumn _prepareDataView:aDataView forRow:aRow];
}
// Only forcefully bind the raw content object if the data source didn't already provide a formatted value
else if (_contentBindingExplicitlySet && !providedByDataSource)
{
[self _prepareContentBindedDataView:aDataView forRow:aRow];
}
}
- (void)_prepareContentBindedDataView:(CPView)dataView forRow:(CPInteger)aRow