Creating a Custom Add or Edit Dialog in LightSwitch C# Beta2
Thanks to Sheel Shah for his informative posting Creating a Custom Add or Edit Dialog (Sheel Shah). Here is a work up of his solution in C# for Beta2, with allowing for the user clicking the X to close the child modal window:
using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using System.Windows.Controls;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
namespace LightSwitchApplication
{
public partial class Application
{
}
public class DialogHelper
{
Microsoft.LightSwitch.Client.IScreenObject _screen;
Microsoft.LightSwitch.Client.IVisualCollection _collection;
String _dialogName;
bool _isEditing;
bool _isOK; //added to allow for user clicking on X
bool _doOnce; //added to allow only one closing handler
IEntityObject _entity;
public DialogHelper(Microsoft.LightSwitch.Client.IVisualCollection visualCollection,
String dialogName)
{
_screen = visualCollection.Screen;
_collection = visualCollection;
_dialogName = dialogName;
_isOK = false; //added to allow for user clicking on X
_doOnce = true; //added to allow only one closing handler
}
public void InitializeUI()
{
// following moved to BaseOpenDialog as workaround for beta2
//bug: Modal window does not fire control available on open.
//_screen.FindControl(_dialogName).ControlAvailable +=
// new EventHandler<ControlAvailableEventArgs>(DialogHelper_ControlAvailable);
//_screen.FindControl(_dialogName).ControlUnavailable +=
// new EventHandler<ControlUnavailableEventArgs>(DialogHelper_ControlUnavailable);
}
void DialogHelper_ControlAvailable(object sender, ControlAvailableEventArgs e)
{
if (_doOnce)
{
ChildWindow childwindow = e.Control as ChildWindow;
childwindow.Closed += new EventHandler(childwindow_Closed);
_doOnce = false;
}
_screen.FindControl(_dialogName).ControlUnavailable -= new
EventHandler<ControlUnavailableEventArgs>(DialogHelper_ControlUnavailable);
}
void childwindow_Closed(object sender, EventArgs e)
{
if (_entity != null)
{
if (_isOK)
{
(_entity.Details as System.ComponentModel.IEditableObject).EndEdit();
}
else
{
if (_isEditing)
{
//cancel edit on close without ok (cancel or click X)
(_entity.Details as System.ComponentModel.IEditableObject).CancelEdit();
}
else
{
//on add if not ok discard, do not add blank row
_entity.Details.DiscardChanges();
}
}
_isOK = false;
}
}
public bool CanEditSelected()
{
return _collection.CanEdit && (_collection.SelectedItem != null);
}
public bool CanAdd()
{
return _collection.CanAddNew;
}
public void AddEntity()
{
_isEditing = false;
_collection.AddNew();
_screen.FindControl(_dialogName).DisplayName = "Add " +
_collection.Details.GetModel().ElementType.Name;
BaseOpenDialog();
}
public void EditSelectedEntity()
{
_isEditing = true;
_screen.FindControl(_dialogName).DisplayName = "Edit " +
_collection.Details.GetModel().ElementType.Name;
BaseOpenDialog();
}
private void BaseOpenDialog()
{
_entity = _collection.SelectedItem as IEntityObject;
if (_entity != null)
{
Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() =>
{
(_entity.Details as System.ComponentModel.IEditableObject).EndEdit();
(_entity.Details as System.ComponentModel.IEditableObject).BeginEdit();
}
);
_screen.OpenModalWindow(_dialogName);
//after beta 2 following can be moved to IntializeUI
_screen.FindControl(_dialogName).ControlAvailable += new
EventHandler<ControlAvailableEventArgs>(DialogHelper_ControlAvailable);
_screen.FindControl(_dialogName).ControlUnavailable += new
EventHandler<ControlUnavailableEventArgs>(DialogHelper_ControlUnavailable);
}
}
void DialogHelper_ControlUnavailable(object sender, ControlUnavailableEventArgs e)
{
_screen.FindControl(_dialogName).ControlAvailable -= new
EventHandler<ControlAvailableEventArgs>(DialogHelper_ControlAvailable);
}
public void DialogOK()
{
_isOK = true;
_screen.CloseModalWindow(_dialogName);
}
public void DialogCancel()
{
_screen.CloseModalWindow(_dialogName);
}
}
}
With calling code:
using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
namespace LightSwitchApplication
{
public partial class EditableCustomersGrid
{
private DialogHelper customersDialogHelper;
partial void EditableCustomersGrid_InitializeDataWorkspace(
System.Collections.Generic.List<IDataService> saveChangesTo)
{
customersDialogHelper = new DialogHelper(this.Customers, "CustomerEditDialog");
}
partial void EditableCustomersGrid_Created()
{
//customersDialogHelper.InitializeUI(); //not for beta2
}
partial void gridAddAndEditNew_CanExecute(ref bool result)
{
result = customersDialogHelper.CanAdd();
}
partial void gridAddAndEditNew_Execute()
{
customersDialogHelper.AddEntity();
}
partial void gridEditSelected_CanExecute(ref bool result)
{
result = customersDialogHelper.CanEditSelected();
}
partial void gridEditSelected_Execute()
{
customersDialogHelper.EditSelectedEntity();
}
partial void EditDialogOK_Execute()
{
customersDialogHelper.DialogOK();
}
partial void EditDialogCancel_Execute()
{
customersDialogHelper.DialogCancel();
}
}
}
Note: a reference to System.Windows.Controls has been added to the Client project.
Thanks for sharing the C# version of this!