partial void btnCreateCar(Foundation.NSObject sender) { NSWindow w = tableView.Window; // try to end any editing that is taking place bool editingEnded = w.MakeFirstResponder(w); if (!editingEnded) { Console.WriteLine("Unable to end editing"); return; } NSUndoManager undo = this.UndoManager; // Has an edit occurred already in this event? if (undo.GroupingLevel > 0) { // Close the last group undo.EndUndoGrouping(); // Open a new group undo.BeginUndoGrouping(); } // Create the object // Should be able to do arrayController.NewObject, but it returns an NSObjectController // not an NSObject and also causes an InvalidCastException // BUG: https://bugzilla.xamarin.com/show_bug.cgi?id=25620 // var c = arrayController.NewObject; // Workaround - not available in Unified API... due to protection level. // Car c = (Car)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(arrayController.Handle, Selector.GetHandle ("newObject"))); // Plus I can't figure out how to get the Car object from NSObjectController. Ah, this is due to above bug. // Creating my own Person object instead Car c = new Car(); // Add it to the content array of arrayController arrayController.AddObject(c); // Re-sort (in case the user has sorted a column) arrayController.RearrangeObjects(); // Get the sorted array NSArray a = NSArray.FromNSObjects(arrayController.ArrangedObjects()); // Find the object just added nint row = -1; for (nuint i = 0; i < a.Count; i++) { if (c == a.GetItem <Car>(i)) { row = (nint)i; break; } } Console.WriteLine("Starting edit of {0} in row {1}", c, row); // Begin the edit of the first column tableView.EditColumn(0, row, null, true); }
public void ObserveValueForKeyPath(NSString keyPath, NSObject obj, NSDictionary change, IntPtr context) { if (context != this.Handle) { // If the context does not match, this message // must be intended for our superclass base.ObserveValue(keyPath, obj, change, context); return; } NSUndoManager undo = this.UndoManager; NSObject oldValue = change.ObjectForKey(ChangeOldKey); // NSNull objects are used to represent nil in a dictinoary if (oldValue == NSNull.Null) { oldValue = null; } Console.WriteLine("oldValue = {0}", oldValue); NSArray args = NSArray.FromObjects(new object[] { keyPath, obj, oldValue }); undo.RegisterUndoWithTarget(this, new Selector("changeKeyPathofObjecttoValue:"), args); undo.SetActionname("Edit"); // Sort if necessary arrayController.RearrangeObjects(); // Keep the row selected. // Without this, the row is selected in gray (tableView loses focus) and the arrow keys don't work to navigate to other items // and the return key does not trigger editing of the item again. tableView.EditColumn(0, tableView.SelectedRow, null, false); }
public void UndoRemove(NSObject o) { NSIndexSet selections = tableView.SelectedRows; Person p = ((NSArray)o).GetItem <Person>(0); NSNumber index = ((NSArray)o).GetItem <NSNumber>(1); Console.WriteLine("Undoing Remove person"); // Undo add NSUndoManager undo = this.UndoManager; NSArray args = NSArray.FromObjects(new object[] { p }); undo.RegisterUndoWithTarget(this, new Selector("undoAdd:"), args); StartObservingPerson(p); Employees.Insert(index.Int32Value, p); tableView.ReloadData(); // have to push any previous selections that are after this up one for (int i = Employees.Count - 1; i > index.Int32Value; i--) { if (tableView.IsRowSelected(i - 1)) { tableView.DeselectRow(i - 1); tableView.SelectRow(i, true); } } // Uncomment to reselect added rows. However I decided that maintaining the current selection is more important // So as not to change the items the user has selected. // tableView.SelectRow(index.Int32Value, true); SortData(tableView.SortDescriptors); }
public void UndoAdd(NSObject o) { // try to end any editing that is taking place if (!StopEditing()) { return; } Person p = ((NSArray)o).GetItem <Person>(0); int index = Employees.IndexOf(p); Console.WriteLine("Undoing Add person"); // Add the inverse of this operation to the undo stack NSUndoManager undo = this.UndoManager; NSArray args = NSArray.FromObjects(new object[] { p, new NSNumber(index) }); undo.RegisterUndoWithTarget(this, new Selector("undoRemove:"), args); StopObservingPerson(p); // have to push any previous selections that are after this up one for (int i = index; i < Employees.Count; i++) { if (tableView.IsRowSelected(i)) { tableView.DeselectRow(i); tableView.SelectRow(i - 1, true); } } Employees.Remove(p); tableView.ReloadData(); }
partial void createEmployee(Foundation.NSObject sender) { NSUndoManager undo = this.UndoManager; // Has an edit occurred already in this event? if (undo.GroupingLevel > 0) { // Close the last group undo.EndUndoGrouping(); // Open a new group undo.BeginUndoGrouping(); } Person newEmployee = new Person(); Console.WriteLine("Adding {0} to {1}", newEmployee, Employees); // Undo add NSArray args = NSArray.FromObjects(new object[] { newEmployee }); undo.RegisterUndoWithTarget(this, new Selector("undoAdd:"), args); undo.SetActionname(NSBundle.MainBundle.LocalizedString("ADD_PERSON", null)); Employees.Add(newEmployee); StartObservingPerson(newEmployee); tableView.ReloadData(); int row = Employees.IndexOf(newEmployee); Console.WriteLine("Starting edit of {0} in row {1}", newEmployee, row); // Begin the edit of the first column tableView.SelectRow(row, false); tableView.EditColumn(0, row, null, true); }
public override void ViewDidLoad () { base.ViewDidLoad (); View.BackgroundColor = UIColor.Cyan; undoManager = new NSUndoManager (); NSObject target = undoManager.PrepareWithInvocationTarget (this); Console.WriteLine (target); }
public void UndoAdd(NSObject o) { Oval oval = ((NSArray)o).GetItem <Oval>(0); Console.WriteLine("Undoing Add Oval"); // Add the inverse of this operation to the undo stack NSUndoManager undo = this.UndoManager; NSArray args = NSArray.FromObjects(new object[] { oval }); undo.RegisterUndoWithTarget(this, new Selector("undoRemove:"), args); Ovals.Remove(oval); stretchView.Ovals = Ovals; stretchView.NeedsDisplay = true; }
public override void WindowControllerDidLoadNib(NSWindowController windowController) { base.WindowControllerDidLoadNib(windowController); // Add code to here after the controller has loaded the document window stretchView.AddToUndo = new UndoDelegate(delegate(Oval oval) { NSUndoManager undo = this.UndoManager; NSArray args = NSArray.FromObjects(new object[] { oval }); undo.RegisterUndoWithTarget(this, new Selector("undoAdd:"), args); undo.SetActionname("Add Oval"); }); stretchView.Ovals = Ovals; }
public void UndoRemove(NSObject o) { Oval oval = ((NSArray)o).GetItem <Oval>(0); Console.WriteLine("Undoing Remove oval"); // Undo add NSUndoManager undo = this.UndoManager; NSArray args = NSArray.FromObjects(new object[] { oval }); undo.RegisterUndoWithTarget(this, new Selector("undoAdd:"), args); Ovals.Add(oval); stretchView.Ovals = Ovals; stretchView.NeedsDisplay = true; }
public void InsertObjectInCarsAtIndex(Car c, int index) { NSUndoManager undo = this.UndoManager; Console.WriteLine("Adding {0} to {1}", c, Cars); // Add the inverse of this operation to the undo stack NSArray args = NSArray.FromObjects(new object[] { c, new NSNumber(index) }); undo.RegisterUndoWithTarget(this, new Selector("undoAdd:"), args); if (!undo.IsUndoing) { undo.SetActionname("Add Car"); } // Add the car to the array this.StartObservingCar(c); Cars.Insert(c, index); }
public void InsertObjectInEmployeesAtIndex(Person p, int index) { NSUndoManager undo = this.UndoManager; Console.WriteLine("Adding {0} to {1}", p, Employees); // Add the inverse of this operation to the undo stack NSArray args = NSArray.FromObjects(new object[] { p, new NSNumber(index) }); undo.RegisterUndoWithTarget(this, new Selector("undoAdd:"), args); if (!undo.IsUndoing) { undo.SetActionname("Add Person"); } // Add the person to the array this.StartObservingPerson(p); Employees.Insert(p, index); }
public void ObserveValueForKeyPath(NSString keyPath, NSObject obj, NSDictionary change, IntPtr context) { if (context != this.Handle) { // If the context does not match, this message // must be intended for our superclass base.ObserveValue(keyPath, obj, change, context); return; } NSUndoManager undo = this.UndoManager; NSObject oldValue = change.ObjectForKey(ChangeOldKey); // NSNull objects are used to represent nil in a dictinoary if (oldValue == NSNull.Null) { oldValue = null; } Console.WriteLine("oldValue = {0}", oldValue); NSArray args = NSArray.FromObjects(new object[] { keyPath, obj, oldValue }); undo.RegisterUndoWithTarget(this, new Selector("changeKeyPathofObjecttoValue:"), args); undo.SetActionname("Edit"); // Sort if necessary // Not sorting avoids problem discussed in next comment // /// TODO: figure out how to sort after an edit AND hold onto the selection. /// Tried subclassing the NSTextField cell and creating a reference outlet to the arrayController /// But this outlet was always null. Need an outlet collection? /// However it did work properly when I did make a static property holding the array controller that I could /// access via an NSTextField cell subclass. Problem here was when multiple documents were open, /// as it can only reference one array controller at a time. /// /// OK, setting AutoRearrangeContent on the arrayController does the sort automatically after an edit /// but the item is then once again unfocused. // arrayController.RearrangeObjects(); // Keep the row selected. // Without this, the row is selected in gray (tableView loses focus) and the arrow keys don't work to navigate to other items // and the return key does not trigger editing of the item again. /// TODO: Oops - does not work in a view based table view, /// causes stack overflow as this method (ObserveValueForKeyPath) gets called infinitely. // tableView.EditColumn(0, tableView.SelectedRow, null, false); }
public void RemoveObjectFromCarsAtIndex(nint index) { NSUndoManager undo = this.UndoManager; Car c = Cars.GetItem <Car>((nuint)index); Console.WriteLine("Removing {0} from {1}", c, Cars); // Add the inverse of this operation to the undo stack NSArray args = NSArray.FromObjects(new object[] { c, new NSNumber(index) }); undo.RegisterUndoWithTarget(this, new Selector("undoRemove:"), args); if (!undo.IsUndoing) { undo.SetActionname("Remove Car"); } // Remove the person from the array this.StopObservingCar(c); Cars.RemoveObject(index); }
public void ObserveValueForKeyPath(NSString keyPath, NSObject obj, NSDictionary change, IntPtr context) { if (context != this.Handle) { // If the context does not match, this message // must be intended for our superclass base.ObserveValue(keyPath, obj, change, context); return; } NSUndoManager undo = this.UndoManager; NSObject oldValue = change.ObjectForKey(ChangeOldKey); // NSNull objects are used to represent nil in a dictinoary if (oldValue == NSNull.Null) { oldValue = null; } Console.WriteLine("oldValue = {0}", oldValue); NSArray args = NSArray.FromObjects(new object[] { keyPath, obj, oldValue }); undo.RegisterUndoWithTarget(this, new Selector("changeKeyPathofObjecttoValue:"), args); undo.SetActionname(NSBundle.MainBundle.LocalizedString("EDIT", null)); }
partial void deleteSelectedEmployees(Foundation.NSObject sender) { if (!StopEditing()) { return; } // Which row(s) are selected? NSIndexSet rows = tableView.SelectedRows; // Get a list of people to be removed List <Person> removedPersons = new List <Person>(); NSUndoManager undo = this.UndoManager; for (int i = 0; i < rows.Count; i++) { int index = (int)rows.ElementAt(i); Person p = Employees[index]; removedPersons.Add(p); } // remove each Person and add to the undo stack foreach (Person p in removedPersons) { Console.WriteLine("Removing {0} from {1}", p, Employees); // Add the inverse of this operation to the undo stack int index = Employees.IndexOf(p); NSArray args = NSArray.FromObjects(new object[] { p, new NSNumber(index) }); undo.RegisterUndoWithTarget(this, new Selector("undoRemove:"), args); undo.SetActionname(NSBundle.MainBundle.LocalizedString("REMOVE_PERSON", null)); StopObservingPerson(p); Employees.Remove(p); } tableView.ReloadData(); tableView.DeselectAll(this); }