MonoTouch.Dialog : Advanced Editing
I'm trying to put together a detail view that is editable, similar to the iPhone default contacts app.
I have a TableView of contacts and I activate an editable detail view when a cell is selected:
public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path)
{
var editingSection = new Section ("Entity") {
new StringElement ("First name", "enter", _entity.FirstName),
new StringElement ("Last name", "enter", _entity.LastName)
};
var root = new RootElement("Entity Entry") {
editingSection
};
var entityEdit = new EntityEdit (root, true);
ConfigEdit (entityEdit);
dvc.ActivateController(entityEdit);
}
void ConfigEdit (DialogViewController dvc)
{
dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Edit, delegate {
dvc.TableView.SetEditing (true, true);
ConfigDone (dvc);
});
}
void ConfigDone (DialogViewController dvc)
{
dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
dvc.TableView.SetEditing (false, true);
ConfigEdit (dvc);
});
}
The behavior that I want to change is in the ConfigEdit method. When I first show the view, the elements in the editing section should be StringElements. When I switch to edit mode, the elements should change to entry Elements because I want the ability to delete the row, or edit the text 开发者_运维百科inside the element.
Is this possible? Is there a better approach to showing read-only elements until edit mode has been set?
You have a couple of options:
a. You can just change the RootElement with an updated RootElement, or update the individual cells with new cells of the proper type of element to get the desired effect. You could do this by parametrizing your creation:
RootElement CreateRoot (bool editable)
{
return new RootElement (...) {
CreateEditableElement ("foo", bar, editable)
}
}
Element CreateEditableElement (string caption, string content, bool editable)
{
return editable ? EntryElement (caption, content) : StringELement (caption, content)
}
Then you need to call ReloadData after the user has tapped the "Edit" button.
The other thing that you could do is to create a new Element that can switch states based on this information. My blog has a tutorial on how to create new elements:
http://tirania.org/monomac/archive/2011/Jan-18.html
Based on Miguel's answer, here is what I did:
public partial class AppDelegate
{
public void DemoAdvancedEditing ()
{
var root = new RootElement ("Todo list") {
new Section() {
new StringElement ("1", "Todo item 1"),
new StringElement ("2","Todo item 2"),
new StringElement ("3","Todo item 3"),
new StringElement ("4","Todo item 4"),
new StringElement ("5","Todo item 5")
}
};
var dvc = new AdvancedEditingDialog (root, true);
AdvancedConfigEdit (dvc);
navigation.PushViewController (dvc, true);
}
void AdvancedConfigEdit (DialogViewController dvc)
{
dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Edit, delegate {
// Activate editing
// Switch the root to editable elements
dvc.Root = CreateEditableRoot(dvc.Root, true);
dvc.ReloadData();
// Activate row editing & deleting
dvc.TableView.SetEditing (true, true);
AdvancedConfigDone(dvc);
});
}
void AdvancedConfigDone (DialogViewController dvc)
{
dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
// Deactivate editing
dvc.ReloadData();
// Switch updated entry elements to StringElements
dvc.Root = CreateEditableRoot(dvc.Root, false);
dvc.TableView.SetEditing (false, true);
AdvancedConfigEdit (dvc);
});
}
RootElement CreateEditableRoot (RootElement root, bool editable)
{
var rootElement = new RootElement("Todo list") {
new Section()
};
foreach (var element in root[0].Elements) {
if(element is StringElement) {
rootElement[0].Add(CreateEditableElement (element.Caption, (element as StringElement).Value, editable));
} else {
rootElement[0].Add(CreateEditableElement (element.Caption, (element as EntryElement).Value, editable));
}
}
return rootElement;
}
Element CreateEditableElement (string caption, string content, bool editable)
{
if (editable) {
return new EntryElement(caption, "todo", content);
} else {
return new StringElement(caption, content);
}
}
}
精彩评论