erotik film
bodyheat full moves www xxx kajal video la figa che sborra ver video de sexo porno
Luxury replica watches
sex
asyabahis
escort antalya

** THIS SITE IS AN ARCHIVE ** - New Content is at:
BlazorHelpWebsite.com

Jun 14

Written by: Richard Waddell
6/14/2011 10:17 AM  RssIcon

The default Add and Edit screens generated by LightSwitch often don’t allow the control you need to meet the business requirements.  Consider the scenario where an entity must have a password column.  Ideally we’d want the ‘Add’ screen to look something like this:

image

The default Add and Edit screens are inadequate for two reasons.

  • No masked password text box
  • A second password text box is required for matching, requiring a property that doesn’t map to the entity.

Fortunately, it’s easy to supply your own custom Add and Edit screens, and often a single screen can serve as both. Unfortunately there’s no way to display the screen modally, so when the user clicks the 'Add’ button they are taken to a new tabbed screen. On completion control returns to the original screen, but it’s not the ideal user experience.

Fortunately it’s possible to supply a modal window, unfortunately it takes a little more work than just creating a screen, but not as much as you might think. Thanks to Michael Washington for the Modal Window stuff.

I’m going to take you through the steps required to create the modal window you see above for adding an entity and one for editing. I wouldn’t be surprised if you could use one window for both, but let’s keep it simple for now.

Create The Subscriber Entity and Screen

First, create a Subscriber entity with UserName and Password properties:

image

Create an Editable Grid Screen:

image

Add A Modal Window Group

image

A Rows Layout Group is created by default; change it to a Modal Window:

image

Drag the UserName and Password properties under the Modal Window:

image

Change the name to AddSubscriber and uncheck the ‘Is Visible’ checkbox.

image

Add a ReEntered Password Property and Bind to the ReEntered Password TextBox

Click on ‘Add Data Item…’ and add a ReEnteredNewPassword string property that is not required:

image

Drag the ReEnteredNewPassword property to the Modal Window:

image

We need a Subscriber for the add screen to use, so add a NewSubscriber property:

image

Override the Add Button Execute Code

Before we get into binding or custom controls, let’s hook up the Add Button:

image

 

partial void gridAddAndEditNew_Execute()
{
    this.OpenModalWindow("AddSubscriber");
}

Resulting in:

image

We’re on the right track. As you probably already suspect, the User Name and Password boxes are grayed-out because the NewSubscriber property is null; we have a property, but no one is home. So we’ll new up the property and initialize the ReEnteredNewPassword property at the same time:

partial void gridAddAndEditNew_Execute()
{
    NewSubscriber = new Subscriber();
    ReEnteredNewPassword = String.Empty;
    this.OpenModalWindow(ADD_SUBSCRIBER_WINDOW);
    this.FindControl(ADD_SUBSCRIBER_WINDOW).ControlAvailable += 
        new EventHandler<ControlAvailableEventArgs>(NewSubscriber_WindowAvailable);
}
Actually, we’re a little ahead of ourselves, but this allows me to point out the value of constants when dealing with Modal Window group names. You’ll be using each one more than twice, as a matter of fact, so it makes sense to create a constant, especially with all this new-fangled binding. Why in my day if it compiled you knew it was good to go. Punch

With just that much code we have a workable Add Subscriber window. As you can dimly see below, the values entered in the New Subscriber window show up in the Subscriber list – our NewSubscriber becomes part of the DataWorkspace Subscriber collection and so is bound to the list just like all the other Subscribers; now it can be saved or deleted just as though we had added it directly to the list.

image

Formatting

Before moving on, let’s clean up the UI a little bit. This is one of the things that’s so cool about LightSwitch. All you have to do to align the columns is add a Rows Layout group. The trickiest part is clicking the right place with the right button.

Right-click on the little down arrow between ‘Modal Window’ and ‘Add Subscriber’ then click on Add Group:

image

Resulting in:

image

Now drag the three controls to the Rows Layout Group and change ReEnteredNewPassword Display Name to ReEnter:

image

Who’s got a mouse and doesn’t need StackPanels or Grids? This nerd!!!!

image

Converting to Custom Controls

Ok, on to the PasswordBox Custom Controls. Left-click on the down-arrow between the label icon and ‘Password’ and select Custom Control:

image

Change the Password Custom Control Custom Control (?) property:

image

Select System.Windows.Controls.PasswordBox:

image

Do the same for ReEnteredNewPassword.

If you run this now, you’ll find that the Password boxes are masked, but the binding no longer works; text entered in the Password boxes does not show up in the new row in the list of Subscribers.

Binding the PasswordBox Controls

In the code below I’ve set the binding for all four password boxes, two for Add and two for Edit. Thanks to Tim Leung for the whole masked password and binding thing.

private const string EDIT_SUBSCRIBER_WINDOW = "EditSubscriber";
private const string ADD_SUBSCRIBER_WINDOW = "AddSubscriber";
private const string EDIT_PASSWORD_CONTROL = "EditScreenPassword";
private const string EDIT_PASSWORD_REENTER_CONTROL = "EditScreenReEnterPassword";
private const string NEW_PASSWORD_CONTROL = "AddScreenPassword";
private const string NEW_PASSWORD_REENTER_CONTROL = "AddScreenReEnterPassword";
private const string PASSWORD_MATCH_ERROR_TEMPLATE = "Reentered Password does not match Password in {0}";
partial void EditableSubscribersGrid_Created()
{
    // Bind the four Password properties to the PassWordBox Screen CustomControls
    // Edit Password Box
    IContentItemProxy proxyEditPassword = 
        this.FindControl(EDIT_PASSWORD_CONTROL);
    // WE are binding to the PasswordProperty dependency property of the PassWordBox, 
    proxyEditPassword.SetBinding
        (System.Windows.Controls.PasswordBox.PasswordProperty, 
        "Value", System.Windows.Data.BindingMode.TwoWay);
    // Edit ReEnter Password Box
    IContentItemProxy proxyReEnteredEditPassword = 
        this.FindControl( EDIT_PASSWORD_REENTER_CONTROL);
    proxyReEnteredEditPassword.SetBinding
        (System.Windows.Controls.PasswordBox.PasswordProperty, 
        "Value", System.Windows.Data.BindingMode.TwoWay);
    // New Passowrd Box
    IContentItemProxy proxyNewPassword = 
        this.FindControl(NEW_PASSWORD_CONTROL);
    proxyNewPassword.SetBinding
        (System.Windows.Controls.PasswordBox.PasswordProperty, 
        "Value", System.Windows.Data.BindingMode.TwoWay);
    // New ReEnter Password Box
    IContentItemProxy proxyReEnteredNewPassword = 
        this.FindControl(NEW_PASSWORD_REENTER_CONTROL);
    proxyReEnteredNewPassword.SetBinding
        (System.Windows.Controls.PasswordBox.PasswordProperty, 
        "Value", System.Windows.Data.BindingMode.TwoWay);
}

Formatting At Run Time

If you run the application now you’ll find that you can successfully  add new Subscribers. But the UI needs a little work. Let’s do that at run time so we can experiment without having to re-build the application. To enable this capability, run the application in debug mode by hitting F5. After you click the Add button you’ll see:

image

The issue is that the Password boxes are unsightly. We can get into design mode by clicking on the ‘Design Screen’ icon on the upper-right corner of the page:

image

You’ll see something like this.

image

With some re-sizing and scrolling we can focus on the Sizing properties. Let’s set Horizontal Alignment to Stretch for both Password and ReEnter:

image

Click on Save and then the Add Button:

image

Maybe you’d like to size the textboxes to more closely match the likely input. Click on Design Screen, change the Horizontal Alignment back to Left, and set MinWidth to whatever you prefer, I chose 150:

image

Why, you ask, are the User Name and Password captions bold and ReEnter is not? I have not a clue. The captions are set through the Custom Control Display Name, but I don’t see any setting to affect the font weight. Doesn’t mean it can’t be changed, but I don’t know how to do it.

Validate the Password

Ok, now let’s add some validation, which consists of requiring that the values entered into the Password and ReEnter textboxes match. We already have our ReEnteredNewPassword property and it’s bound to the ReEnter Custom Control so we can go directly to validation

image

And here’s the code:

partial void ReEnteredNewPassword_Validate(ScreenValidationResultsBuilder results)
{
    if (this.NewSubscriber != null && 
        this.NewSubscriber.Password != null && 
        ReEnteredNewPassword != this.NewSubscriber.Password)
        results.AddPropertyError
            (String.Format(PASSWORD_MATCH_ERROR_TEMPLATE, "New Subscriber"));
}

Pretty straightforward. Now if the entered password values don’t match:

image

The validation issue will appear as soon as you tab away from Password and remain until you enter a matching value in Re-Enter, which is a bit naggy, but kind of unavoidable given the nature of binding.

Add and Cancel Buttons

This is serviceable, but a bit clumsy in that you can only cancel an add by deleting it from the Subscriber list after you exit the Add Subscriber window. We need Add and Cancel buttons. Right-click where indicated below and select Add Button:

image

Name it SubmitAdd:

image

Change the Display Name to ‘Add’. Right-click where indicated below and select ‘Edit Execute Code’:

image

It turns out all we have to do is close the window. As you saw above, the new Subscriber becomes part of the collection on creation, and remains so unless deleted.

partial void SubmitAdd_Execute()
{
    CloseAddSubscriberWindow();
}
private void CloseAddSubscriberWindow()
{
    this.CloseModalWindow(ADD_SUBSCRIBER_WINDOW);
    this.FindControl(ADD_SUBSCRIBER_WINDOW).IsVisible = false;
}

Notice that although OpenModalWindow sets the control IsVisible property to true, CloseModalWindow does not set it to false. If you don’t set it yourself you see this at the bottom of the page:

image

Add the Cancel button and the following CanExecute code:

partial void CancelAdd_Execute()
{
    CancelAddSubscriberChanges();
    CloseAddSubscriberWindow();
}
private void CancelAddSubscriberChanges()
{
    foreach (Subscriber subscriber in this.DataWorkspace.ApplicationData.Details.
                                GetChanges().AddedEntities.OfType<Subscriber>())
        subscriber.Details.DiscardChanges();
}

Subscribing to the Modal Window Close Event

That covers the buttons, but what if the user clicks on the little ‘x’ in the upper-right corner. That should be the same as cancel, but as we’ve seen it’s not. We intercept that event by subscribing to the Modal Window close event. That requires a little setup. You saw a preview back when I showed you the Add button event handler:

partial void gridAddAndEditNew_Execute()
{
    NewSubscriber = new Subscriber();
    ReEnteredNewPassword = String.Empty;
    this.OpenModalWindow(ADD_SUBSCRIBER_WINDOW);
    this.FindControl(ADD_SUBSCRIBER_WINDOW).ControlAvailable += 
        new EventHandler<ControlAvailableEventArgs>(NewSubscriber_WindowAvailable);
}

So I’ll transition now to the event handler for the Edit button so we can cover the Edit Modal Window and the close event handling at the same time. The only difference in initialization is that we now have an existing Subscriber to work with.

As to the close event, we don’t have access to the underlying control until the ControlAvailable event, so that’s where we subscribe to the closed event. The nullable ChildWindow.DialogResult property will be null if the window was closed with the ‘x’, so the changes are canceled.

partial void gridEditSelected_Execute()
{
    // The Edit Button has been selected
    ReEnteredEditPassword = this.Subscribers.SelectedItem.Password;
    this.OpenModalWindow(EDIT_SUBSCRIBER_WINDOW);
    // We need to add a Closed event handler to the underlying control which we have access to when we catch the ControlAvailable event
    this.FindControl(EDIT_SUBSCRIBER_WINDOW).ControlAvailable += new EventHandler<ControlAvailableEventArgs>(EditSubscriber_WindowAvailable);
}
void EditSubscriber_WindowAvailable(object sender, ControlAvailableEventArgs e)
{
    this.FindControl(EDIT_SUBSCRIBER_WINDOW).ControlAvailable -= new EventHandler<ControlAvailableEventArgs>(EditSubscriber_WindowAvailable);
    ((ChildWindow)e.Control).Closed += new EventHandler(EditSubscriber_Closed);
}
void EditSubscriber_Closed(object sender, EventArgs e)
{
    ((ChildWindow)sender).Closed -= new EventHandler(EditSubscriber_Closed);
    if (!((ChildWindow)sender).DialogResult.HasValue)
        CancelEditSubscriberChanges();
    CloseEditSubscriberWindow();
}

The validation could use some fine-tuning in that in the ‘Add Subscriber’ window you can ignore the mismatched password warning and click the Add button, which should be disabled. Then you’re stuck with a validation error you can only clear by clicking ‘Refresh’. Same problem if you click the ‘x’ or Cancel button with a mismatched password error showing. 

The Add button is pretty easy to handle.

image

partial void SubmitAdd_CanExecute(ref bool result)
{
    result = this.NewSubscriber != null &&
        this.NewSubscriber.Password != null &&
        ReEnteredNewPassword == this.NewSubscriber.Password;
}

image

The ‘x’ and Cancel Button situations where the passwords are mismatched can be handled by setting NewSubscriber to null. This causes the validation code to ignore the mismatch:

private void CancelAddSubscriberChanges()
{
    foreach (Subscriber subscriber in this.DataWorkspace.ApplicationData.Details.
                                GetChanges().AddedEntities.OfType<Subscriber>())
        subscriber.Details.DiscardChanges();
    NewSubscriber = null;
}

And Robert is your Father’s brother!!!

The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx

Tags:
Categories:

28 comment(s) so far...


Michael, I believe Lightswitch will automatically "bold" prompts for required fields.

By Steve Fabian on   6/14/2011 3:23 PM

thanks nice

By Mae on   6/14/2011 3:23 PM

@Steve Fabian - Thanks, I should have realized that. It brings up an interesting quandary. The re-entered password should be required, but only when the relevant modal window is being validated. Otherwise you get 'Reentered password required' validation errors at inappropriate times. Probaby that can be coded around. ITM the only downside seems to be that the caption is not bold.

By Richard Waddell on   6/21/2011 5:42 AM

Richard,

The 'Name' and 'Password' labels are bold because they are mandatory fields in the table, the local property 'ReEnter' is not.

hth,
Ueli

By Ueli Sonderegger on   6/14/2011 4:09 PM

@Ueli - Ok, now you're just rubbing it in. :)

By Richard Waddell on   6/14/2011 4:10 PM

@Mae Thanks.

By Richard Waddell on   6/14/2011 4:11 PM

Great one... But can i know the features of lightswitch? please help.

By Er. Rajesh on   6/17/2011 5:27 AM

Hi.
I have a problem...
When I click add from the command bar, the modal form opens but in the ID and Description text box are set with the value of the current row of the datagrid.

In the Execute event I do this:
partial void gridAddAndEditNew_Execute()
{
NewModalita = new ModalitaPag();
this.OpenModalWindow("NewModalita");
}

Can you help me please?

By pippo876 on   6/17/2011 5:27 AM

Is your Entity type ModalitaPag? If so, Your screen controls need to be bound to NewModalita.Id and NewModalita.Description. It sounds like they are bound to ModalitaPags.SelectedItem.ID and Description.

By Richard Waddell on   6/17/2011 5:05 PM

I have made an improvement in your solution that I want to share:
Instead of adding NewSubscriber (to follow your example) I added CurrentSubscriber.
This allows easily using the same ModalDialog for New and Edit as the dialog is bound to this CurrentSubscriber instance.

in gridAddAndEditNew_Execute() you set CurrentSubscriber = new Subscriber()

in gridEditSelected_Execute() you just show the modal dialog as in

Subscribers_SelectionChanged() you set CurrentSubscriber = this.Subscribers.SelectedItem
I prefer to do it in selection changed rather that in gridEditSelected_Execute() to avoid any focus issues nulling SelectedItem.

Also to cancel changes all you have to do is CurrentSubscriber.Details.DiscardChanges().

In return for sharing these (you started it :-)) I would to ask if you or anyone reading can tell me how to check for validation errors in the screen in order to enable or disable the Submit button. I know how you can force validation but I don't know how one can check if there are any errors at runtime.

Thanks for the fine sample

By Kostas Christodoulou on   6/21/2011 5:40 AM

Regarding my previous post although not moderated yet, I found a way to achieve what I wanted, but with a rather case specific approach.
Checking this.CanSave in the view is a good way, but the more complex the view the less appropriate the solution. In any case the custom code in my View (my Object is a Color object) looks like this:

public partial class ColorsListDetail
{
private static string controlNameColorEditor = "AddEditColor";
partial void ColorListAddAndEditNew_CanExecute(ref bool result)
{
// Write your code here.

}

partial void ColorListAddAndEditNew_Execute()
{
CurrentColor = new Color();
this.OpenModalWindow(controlNameColorEditor);
}

partial void ColorListEditSelected_Execute()
{
this.OpenModalWindow(controlNameColorEditor);
}

partial void Colors_SelectionChanged()
{
CurrentColor = this.Colors.SelectedItem;
}

partial void SaveEditedColor_Execute()
{
// this is to handle the special case where the last field edited was not validated
// before pressing the "Submit" button and validation errors were collected after executing
if (this.CanSave)
CloseColorEditWindow();
}

private void CloseColorEditWindow()
{
this.CloseModalWindow(controlNameColorEditor);
this.FindControl(controlNameColorEditor).IsVisible = false;
}

partial void CancelChanges_Execute()
{
CancelEditChanges();
CloseColorEditWindow();
}

private void CancelEditChanges()
{
CurrentColor.Details.DiscardChanges();
}

partial void SaveEditedColor_CanExecute(ref bool result)
{
this.FindControl("SaveEditedColor").Focus();
result = this.CanSave;
}
}

I hope it's not inappropriate to post all that code, but, hey, that's what community is all about ;-)

By kchristo on   6/21/2011 5:40 AM

@kchristo - I'm haven't been able to look at your code in enough detail yet, so I may be mis-understanding, but why can't you disable the Submit button in SubmitAdd_CanExecute?

By Richard Waddell on   6/21/2011 4:55 PM

I'm trying to follow your example, but when I'm overriding the Add button and adding the line for the event handler (this.FindControl("AddSubscriber").ControlAvailable += new EventHandler(NewSubscriber_WindowAvailable);)

I get an error that says NewSubscriber_WindowAvailable does not exist in the current context.
Is this supposed to be defined somewhere?

thanks

By Dave on   6/21/2011 4:42 PM

@Dave - I probably generated the event handler by typing "+=" then hitting the tab key twice. You should a tooltip telling you to press Tab when you type in "+=". I think I changed the name of the event handler to NewSubscriber_WindowAvailable manually.At any rate, if you download the project you should see it as the very next method after the code you describe. If you look at the next to last code block in the article you'll see the analogous code for EditSubscriber, EditSubscriber_WindowAvailable.

By Richard Waddell on   6/21/2011 4:58 PM

Hi Dave
I can do that but what I want to do is not dublicate code. I already have custom validation on the Color object and I don't want to copy this code to the _CanExecute method.
The thing is I cannot decide if there are validation issues at runtime. As I mentioned in a previous post I used CanSave property of the ViewModel, but this works as long as there is only one "editable" object type in the View. In my case I only have Colors. But if I had Colors and ColorSets that could be edited (not a good practice but could happen) and there were validation issues regarding a ColorSet for example I would be able to save the Color edited either. So that's why I was wondering if there is a way at runtime to decide if a specific object has validation issues.
Thanks and by the way I believe you will find the way of implementing one mechanism for add and edit interesting.

By kchristo on   6/22/2011 5:41 AM

@kchristo It's good practice to disable the Submit button when an update will fail. Often You can put your validation code in Common and call it from both places. Again, I haven't had time to look at your code closely, so I may be wrong about this particular case.

By Richard Waddell on   6/22/2011 5:43 AM

Hi Richard, I have worked on your sample and created an infrastructure to support all these for any screen.
I posted 2 samples in msdn.com including many references back to this original article. I first wanted to post here in lightswitchhelpwebsite.com but I didn't find a way (what one can do to be able to post a sample). So, feeling that the topic you are dealing with in this post is very common and would be interesting to a lot of people, I posted a sample to msdn.com. If you are interested you can find it here

http://code.msdn.microsoft.com/Managing-Custom-AddEdit-5772ab80

This is a revision to the original sample posted yesterday

http://code.msdn.microsoft.com/Managing-Custom-AddEdit-ab1c6b58

where I make all the references to this site and this post. I found it extremely usefull and I want to thank you once again.

By kchristo on   6/24/2011 5:29 AM

@kchristo - Thanks, I'll check it out.

By Richard Waddell on   6/24/2011 5:31 AM

Richard, would you happen to know how can I post code samples in this site. I am working on developing a LOB application framework based on LightSwitch, and being a community believer (although mostly receiving up to now than offering), I want to share. Is the forum the only place I could post code?
Sorry if I am troubling you...

By kchristo on   7/8/2011 3:46 PM

Good morning,

I'm trying to open a modal window to fill a date field when a status list is changed, but I cant find the way to do it, because the change method is in the entity and you cannot open a modal window from the entity. Can someone help me, please?

Thanks,

Javier Aragón

By Mash_2k on   9/29/2011 5:14 PM

i'm going to try it, thanks a lot

By code geass on   9/29/2011 6:56 PM

Javier,

Sorry for the delay in responding.

I don't think you can prompt for the date on an entity property change event. Probably you'll need a custom control that handles whatever value you are now trying to handle throught the ._Changed event. Then subscribe to the changed event on that control.

Richard






By Richard Waddell on   9/29/2011 6:55 PM

Many thanks!!

By the gamer on   10/24/2011 7:38 AM

the gamer,

You're very welcome!!!

By Richard Waddell on   10/24/2011 7:39 AM

Richard,
Excellent example! I appreciate how you provide step by step screen shots and code snippets, it was very helpful for a LightSwitch rookie like myself.
I have one suggestion related to the modal window "Closed" event, which I found by accident while debugging. If you press the "Enter" key when the modal window is open for either adding a new entity, the window closes but the new entity will not be discarded from the collection. That is because the CancelAddSubscriberChanges() method is only called from either the

1. CancelAdd_Execute() event or
2. the "Closed" event

The CancelAdd_Execute() event is only executed when the Cancel button is clicked.
Your existing "Closed" event only handles clicking the "X" on the window by checking if the DialogResult is null, as you have shown in this code:

if (!((ChildWindow)sender).DialogResult.HasValue)
CancelAddSubscriberChanges();

However, when you press the "Enter" key, the DialogResult is not null, it has a value of "True", therefore skipping the call to CancelAddSubscriberChanges().

This can be fixed by changing the following line from

((ChildWindow)e.Control).Closed += new EventHandler(EditSubscriber_Closed);

to

((ScreenChildWindow)e.Control).Closed += new EventHandler(EditSubscriber_Closed);

(you may need to add a Reference to Microsoft.LightSwitch.Runtime.Shell.Framework;)

then change the Closed event to

void EditSubscriber_Closed(object sender, EventArgs e)
{
ScreenChildWindow window = (ScreenChildWindow)sender;
window.Closed -= new EventHandler(EditSubscriber_Closed);
if (window.DialogResultCancel)
{
CancelAddSubscriberChanges();
}
CloseEditSubscriberWindow();
}

Now you can remove the call to the CancelAddSubscriberChanges() method in your CancelAdd_Execute() event, because when it is now handled in the Closed event.

By tomb69 on   2/23/2012 5:35 PM

Hi tomb69,

Thanks for the tip. You don't sound like a rookie.

Richard

By Richard Waddell on   2/23/2012 5:37 PM

Richard,

Nice post! Anyway to get the red boxes around passwords on validation error? I assume there is something missing in binding of custom control, but what?

TIA,
Josh

By jbooker on   10/20/2012 6:54 AM

Josh,

Thanks. I left that validation as an exercise for the reader. :)

Seriously, off the top of my head I don't know the answer and I'm just too slammed to look into it.

By Richard Waddell on   10/20/2012 6:57 AM

Your name:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation