CRUD LightSwitch in five Minutes (or less)

Summary:
Objective: Create usable CRUD with LightSwitch in few minutes.

Methods: With a few changes to the design of the screen and some quick snippets can configure a Detail List screen for use as custom CRUD.

Results Allow create usable CRUDS.

Conclusions:LightSwitch automatically generates screens to edit or add records, initially say wow!, But minutes later just thinking it would be better to have more control over this.
The acronym CRUD. (C) reate, (R) ead, (U) pdate, (D) elete tables allow us to maintain our database.
We can make custom screens (Details Screen) or (New Screen) to override the automatic behavior, but this for me almost always has disadvantages:

Disadvantages basic technique.
– We must create additional screens to update and add many screens with few content of use that fill our screens list.
– We generate screens are generated as tabs rather than modal windows. It’s pretty ugly to see a tab with just one or two fields.
– For example, 50 data tables 150 equivalent to maintenance screens.
– It’s convoluted and I think you lose a lot of productivity LightSwitch
– We should only do so if it were justifiable.

What is known?
Here you can see other ways to solve the problem:

http://msdn.microsoft.com/en-us/vstudio/ff945359
http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/33/LightSwitch-ndash-Modal-Add-and-Edit-Windows.aspx
http://msdn.microsoft.com/en-us/vstudio/ff949859.aspx

Minute 1
Create a LightSwitch Application



Minute 2
Create Table

Create Screen List Details

Minute 3
Customize Screen:












Minute 4
Add constant string

private const string ADD_POPUP_WINDOW = "addNew";
 

Copy this snippet without changes to class

 /* Copy without changes */    
        private void CloseAddSubscriberWindow(){
            this.CloseModalWindow(ADD_POPUP_WINDOW);            
            this.FindControl(ADD_POPUP_WINDOW).IsVisible = false;
        }
        void AddSubscriber_WindowAvailable(object sender, ControlAvailableEventArgs e)
        {
            this.FindControl(ADD_POPUP_WINDOW).ControlAvailable -= new EventHandler<ControlAvailableEventArgs>(AddSubscriber_WindowAvailable);
            ((ChildWindow)e.Control).Closed += new EventHandler(AddSubscriber_Closed);
 
         }
        void AddSubscriber_Closed(object sender, EventArgs e)
        {
 
             ((ChildWindow)sender).Closed -= new EventHandler(AddSubscriber_Closed);
 
             if (!((ChildWindow)sender).DialogResult.HasValue)
                CancelAddSubscriberWindow();
                CloseAddSubscriberWindow();
        }

Add reference to Windows.Controls

Copy or modify this snippet.

         partial void PersonsListEditSelected_Execute()
        {            
            this.OpenModalWindow(ADD_POPUP_WINDOW);
            this.FindControl(ADD_POPUP_WINDOW).DisplayName = "Editar Persona";
            this.FindControl(ADD_POPUP_WINDOW).ControlAvailable += new EventHandler<ControlAvailableEventArgs>(AddSubscriber_WindowAvailable);
       

        }
        partial void PersonsListAddAndEditNew_Execute()
        {
            this.PersonsSet.AddNew();
            this.OpenModalWindow(ADD_POPUP_WINDOW);
            this.FindControl(ADD_POPUP_WINDOW).DisplayName = "Nueva Persona";
            this.FindControl(ADD_POPUP_WINDOW).ControlAvailable += new EventHandler<ControlAvailableEventArgs>(AddSubscriber_WindowAvailable);
       
        }

Minute 5
Copy or modify this snippet.

  private void CancelAddSubscriberWindow()
        {
            PersonsSet.SelectedItem.Details.DiscardChanges();
        }

Copy or modify this snippet.
Replace btnCancel & btnSave with this:

 partial void btnCancel_Execute()
        {
            CancelAddSubscriberWindow();
            CloseAddSubscriberWindow();
        }
 
         partial void btnSave_Execute()
        {
            this.Save();
            CloseAddSubscriberWindow();
        }
 

Now we have a window to add or edit, without altering the other functions.



Known Issues.
Currently there are no known issues.

Discussions
I think it’s an easy way to control simple screens. Do not think this is the best method but for now it works for me.

Acknowledgements
Special thanks to all the LightSwitch community, especially to Richard Waddell and his post LightSwitch–Modal Add and Edit Windows this have been very helpful to write this post.
Thanks to Ramón Barrena for the review of this article.

Screen Localization for LightSwitch

Summary:

Objective: Find a technique for locating LightSwitch screens in different languages.

Methods: For the approach to this technique of creating a Shell (taking as starting point the official information from Microsoft on a cración Shell), Shell adds this control to change languages​​.

To facilitate debugging of Shell, I used the essential Extension of Jan Van Der Haegen LightSwitchExtensionsMadeEasy.

LightSwitch application and Shell are connected by a agreggator. When changing LighSwitch receives Shell language, reading comes to localized resources. From that time the culture has changed LightSwitch Application. When we open a new screen read the resource file and locate the items in the Screen by DisplayName,

Results: You can locate the screens in multiple languages ​​using resource files resx, but for larger applications can alter this technique to read the resources dynamically and that are not incorporated in the application xap.

Conclusions: It is a first approach and not localize menus or other elements outside the Screen. But the road from here is easy and can be easily extrapolated. This article does not solve the problem of location LightSwitch, it should work as Silverlight or Asp.net but offers an alternative technique with which you can reuse our location files when Microsoft corrects the problem.

What is known?

LightSwitch localization not working as expected. If we need our application to work in 5 different languages ​​at this time the Microsoft solution is to compile the application 5 times. OOP much for this?
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2202505-support-application-in-multiple-languages
http://social.msdn.microsoft.com/Forums/en-US/lightswitchgeneral/thread/90b1f8e9-25ab-4d64-a16f-e64efc191eeb
http://blogs.msdn.com/b/global_developer/archive/2011/09/28/lightswitch-how-to-change-the-run-time-language.aspx
http://lightswitchhelpwebsite.com/Forum/tabid/63/aft/525/Default.aspx

SoftlandingCanada: There is also a commercial solution called DockShell in facing location using PRISM.

http://www.youtube.com/watch?v=47hyerUBIag&feature=youtu.be

What gives?

This technique is easy to find content, can be implemented in any LightSwitch application, no need for a special Shell, Here we have developed one to have somewhere to put the language change, but they could have done from a button on a screen. It is transparent. It’s free.

Introduction.

Thinking that he could not locate resource files LightSwitch with me think only in small applications. Sometimes it is not even necessary that large applications, some countries have different cultures, Catalunya, Belgium, Finland, Cyprus, etc …
My attempts began trying to LighSwitch as Silverlight or ASPNET, creating my resx resource files: AppStrings.en-us.resx, AppStrings.es.resx, AppStrings.ca-ES.resx, AppStrings.fr.resx. After changing played Thread:

Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo ("ca-ES");

I was very happy when I saw that there was trouble in LightSwitch change, so I thought that was sucked.

The next step was the ResourceManager, here my troubles began:

man = new ResourceManager ("LightSwitchApplication.Localization.AppStrings", typeof (AppStrings). Assembly);

I always returned the Invariant Culture culture that was not selected, in the properties of LightSwitch.

From here began the sleepless nights …

Solution
It seems that within LightSwitch ResourceManager not change the resource file by culture, the solution is to create separate resx files and read us as the selected language.

 switch (PresentationParams[0])
                {
                    case "en-US":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_en_US", typeof(AppStrings_en_US).Assembly);
                        break;
                    case "ca-ES":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_ca_ES", typeof(AppStrings_ca_ES).Assembly);
                        break;
                    case "es":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_es", typeof(AppStrings_es).Assembly);
                        break;
                    case "fr":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_fr", typeof(AppStrings_fr).Assembly);
                        break;
                    default:

                        break;
                }

From this moment already correctly read the resource file. All this you can implement without the example that show the practical development of this approach to the localization of LightSwitch.

LocalizationLS, the example
Before I recommend downloading some resources:
Extensions made easy (Jan Van Der Haegen)
CodeLocalization.rar(Snippets of code for this article)

You can test the result of how-to on: http://www.jmlabs.org.es/localizationls

Step 1 of 10
We start by creating a LightSwitch application, with an effort of imagination we call LocalizationLS

Double click on properties and review various things

Here we have selected the default location, ie preselected culture LightSwitch application startup

Activate the useful extension created by Jan Van Der Haegen, we will use for the development of our shell with location

For now close our project and save changes.


Step 2 of 10
Create a new LightSwitch Extension Project

We put the name of Shell Localization

We change the NameSpace of LocalizationShell to LocalizationLS (Double click on properties)

The project Lspkg add a new item named Shell type LSShell


Step 3 of 10
Re-open LocalizationLS

Add LocalizationShell Client to project.

We switch to File View

Add Reference to LocalizationShell

Copy ShellSampleExporter to LocalizationLS.Client

Recorte de pantalla realizado: 22/11/2012 7:30

Modify protection modifier

Modify ShellSampleExporter:

LocalizationShell.Presentation.Shells.Components.LSShell


Step 4 of 10
If you check out the official documentation to create a Shell you can visit:http://msdn.microsoft.com/en-us/library/hh290138.aspx

Replaces the Xaml you just created by that other, is basically the same. but adds a ComboBox for the language change. (Although by now commented).


<UserControl x:Class="LocalizationLS.Presentation.Shells.LSShell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:windows="clr-namespace:System.Windows;assembly=System.Windows.Controls"
    xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:ShellHelpers="clr-namespace:Microsoft.LightSwitch.Runtime.Shell.Helpers;assembly=Microsoft.LightSwitch.Client"
    xmlns:local="clr-namespace:LocalizationLS.Presentation.Shells">

    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/LocalizationShell.Client;component/Presentation/Shells/TextBlockStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>

        <!-- Convert the boolean value indicating whether or not the workspace is dirty to a Visibility value. -->
        <local:WorkspaceDirtyConverter x:Key="WorkspaceDirtyConverter" />

        <!-- Convert the boolean value indicating whether or not the screen has errors to a Visibility value. -->
        <local:ScreenHasErrorsConverter x:Key="ScreenHasErrorsConverter" />

        <!-- Convert the enumeration of errors into a single string. -->
        <local:ScreenResultsConverter x:Key="ScreenResultsConverter" />

        <!-- Convert the current user to a "default" value when authentication is not enabled. -->
        <local:CurrentUserConverter x:Key="CurrentUserConverter" />

        <!-- Template that is used for the header of each tab item: -->
        <DataTemplate x:Key="TabItemHeaderTemplate">
            <Border BorderBrush="{StaticResource ScreenTabBorderBrush}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Style="{StaticResource TextBlockFontsStyle}" Text="{Binding DisplayName}" Foreground="{StaticResource ScreenTabTextBrush}" />
                    <TextBlock Style="{StaticResource TextBlockFontsStyle}" Text="*" 
                               Visibility="{Binding IsDirty, Converter={StaticResource WorkspaceDirtyConverter}}" 
                               Margin="5, 0, 5, 0" />
                    <TextBlock Style="{StaticResource TextBlockFontsStyle}" Text="!" 
                               Visibility="{Binding ValidationResults.HasErrors, Converter={StaticResource ScreenHasErrorsConverter}}" 
                               Margin="5, 0, 5, 0" Foreground="Red" FontWeight="Bold">
                        <ToolTipService.ToolTip>
                            <ToolTip Content="{Binding ValidationResults, Converter={StaticResource ScreenResultsConverter}}" />
                        </ToolTipService.ToolTip>
                    </TextBlock>
                    <Button Height="16"
                            Width="16"
                            Padding="0"
                            Margin="5, 0, 0, 0"
                            Click="OnClickTabItemClose">X</Button>
                </StackPanel>
            </Border>
        </DataTemplate>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="{StaticResource NavShellBackgroundBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="5*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!-- The command panel is a horizontally oriented list box whose data context is set to the  -->
        <!-- CommandsViewModel.  The ItemsSource of this list box is data bound to the ShellCommands -->
        <!-- property.  This results in each item being bound to an instance of an IShellCommand.    -->
        <!--                                                                                         -->
        <!-- The attribute 'ShellHelpers:ComponentViewModelService.ViewModelName' is the manner by   -->
        <!-- which a control specifies the view model that is to be set as its data context.  In     -->
        <!-- case, the view model is identified by the name 'Default.CommandsViewModel'.             -->
        <ListBox x:Name="CommandPanel" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Background="{StaticResource RibbonBackgroundBrush}"
                        ShellHelpers:ComponentViewModelService.ViewModelName="Default.CommandsViewModel"
                        ItemsSource="{Binding ShellCommands}">

            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <!-- Each item in the list box will be a button whose content is the following:         -->
                    <!--    1.  An image, which is bound to the Image property of the IShellCommand         -->
                    <!--    2.  A text block whose text is bound to the DisplayName of the IShellCommand   -->
                    <StackPanel Orientation="Horizontal">
                        <!-- The button be enabled or disabled according to the IsEnabled property of  the -->
                        <!-- IShellCommand.  The handler for the click event will execute the command.  -->
                        <Button Click="GeneralCommandHandler"
                                IsEnabled="{Binding IsEnabled}"
                                Style="{x:Null}"
                                Background="{StaticResource ButtonBackgroundBrush}"
                                Margin="1">

                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="32" />
                                    <RowDefinition MinHeight="24" Height="*"/>
                                </Grid.RowDefinitions>
                                <Image Grid.Row="0"
                                       Source="{Binding Image}"
                                       Width="32"
                                       Height="32"
                                       Stretch="UniformToFill"
                                       Margin="0"
                                       VerticalAlignment="Top"
                                       HorizontalAlignment="Center" />
                                <TextBlock Grid.Row="1"
                                           Text="{Binding DisplayName}"
                                           TextAlignment="Center"
                                           TextWrapping="Wrap"
                                           Style="{StaticResource TextBlockFontsStyle}"
                                           MaxWidth="64" />
                            </Grid>
                        </Button>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <!-- Navigation view is a simple tree view whose ItemsSource property is bound to -->
        <!-- the collection returned from the NavigationItems property of the Navigation  -->
        <!-- view model.                                                                  -->
        <controls:TreeView x:Name="ScreenTree" Grid.Column="0" Grid.Row="1" Grid.RowSpan="2"
                  Background="{StaticResource NavShellBackgroundBrush}"
                  ShellHelpers:ComponentViewModelService.ViewModelName="Default.NavigationViewModel"
                  ItemsSource="{Binding NavigationItems}"
                  Loaded="OnTreeViewLoaded">
            <controls:TreeView.ItemTemplate>
                <!-- Each navigation item may have children, so set up the binding to the -->
                <!-- Children property of the INavigationGroup                            -->
                <windows:HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <!-- Each item in the TreeView is a TextBlock whose text value is bound to the DisplayName property of the INavigationItem -->
                    <TextBlock Style="{StaticResource TextBlockFontsStyle}" 
                               Text="{Binding DisplayName}" 
                               Foreground="{StaticResource NormalFontBrush}" 
                               MouseLeftButtonDown="NavigationItemLeftButtonDown" />
                </windows:HierarchicalDataTemplate>
            </controls:TreeView.ItemTemplate>
        </controls:TreeView>

        <controls:GridSplitter Grid.Column="0"
                          Grid.Row="1"
                          Grid.RowSpan="2"
                          Style="{x:Null}"
                          Width="5"
                          Name="gridSplitter1"
                          Background="Transparent"
                          HorizontalAlignment="Right"
                          VerticalAlignment="Stretch" />

        <!-- Each screen will be displayed in a tab in a tab control.  The individual TabItem -->
        <!-- controls are created in code.                                                    -->
        <controls:TabControl x:Name="ScreenArea"
                             Grid.Column="1"
                             Grid.Row="1"
                             Grid.RowSpan="2"
                             Background="{StaticResource NavShellBackgroundBrush}"
                             SelectionChanged="OnTabItemSelectionChanged">
        </controls:TabControl>

        <!-- The name of the current user is displayed in the lower-left corner of the shell. -->
        <Grid Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Style="{StaticResource TextBlockFontsStyle}" Text="Current User: " Foreground="{StaticResource NormalFontBrush}"/>

            <!-- This TextBlock has its data context set to the CurrentUserViewModel, from which the -->
            <!-- CurrentUserDisplayName property is used to provide the name of the user displayed.  -->
            <TextBlock Grid.Column="1"
                       Style="{StaticResource TextBlockFontsStyle}"
                       ShellHelpers:ComponentViewModelService.ViewModelName="Default.CurrentUserViewModel"
                       Text="{Binding CurrentUserDisplayName, Converter={StaticResource CurrentUserConverter}}"
                       Foreground="{StaticResource NormalFontBrush}"/>

             <!--<local:IdiomasControl Grid.Column="2" />-->
        </Grid>
    </Grid>

</UserControl>


To create the MyScreenObject class

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;

namespace LocalizationLS.Presentation.Shells
{
    using Microsoft.LightSwitch;
    using Microsoft.LightSwitch.Client;
    using Microsoft.LightSwitch.Details;
    using Microsoft.LightSwitch.Details.Client;
    using Microsoft.LightSwitch.Utilities;

    public class MyScreenObject : IScreenObject, INotifyPropertyChanged
    {
        private IScreenObject screenObject;
        private bool dirty;
        private List<IWeakEventListener> dataServicePropertyChangedListeners;

        public event PropertyChangedEventHandler PropertyChanged;

        internal MyScreenObject(IScreenObject screenObject)
        {
            this.screenObject = screenObject;
            this.dataServicePropertyChangedListeners = new List<IWeakEventListener>();

            // Register for property changed events on the details object.
            ((INotifyPropertyChanged)screenObject.Details).PropertyChanged += this.OnDetailsPropertyChanged;

            // Register for changed events on each of the data services.
            IEnumerable<IDataService> dataServices = screenObject.Details.DataWorkspace.Details.Properties.All().OfType<IDataWorkspaceDataServiceProperty>().Select(p => p.Value);

            foreach (IDataService dataService in dataServices)
                this.dataServicePropertyChangedListeners.Add(((INotifyPropertyChanged)dataService.Details).CreateWeakPropertyChangedListener(this, this.OnDataServicePropertyChanged));
        }

        private void OnDetailsPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (String.Equals(e.PropertyName, "ValidationResults", StringComparison.OrdinalIgnoreCase))
            {
                if (null != this.PropertyChanged)
                    PropertyChanged(this, new PropertyChangedEventArgs("ValidationResults"));
            }
        }

        private void OnDataServicePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            IDataService dataService = ((IDataServiceDetails)sender).DataService;

            this.IsDirty = dataService.Details.HasChanges;
        }

        internal IScreenObject RealScreenObject
        {
            get
            {
                return this.screenObject;
            }
        }

        public bool IsDirty
        {
            get
            {
                return this.dirty;
            }
            set
            {
                this.dirty = value;

                if (null != this.PropertyChanged)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsDirty"));
            }
        }

        public ValidationResults ValidationResults
        {
            get
            {
                return this.screenObject.Details.ValidationResults;
            }
        }

        public IScreenDetails Details
        {
            get
            {
                return this.screenObject.Details;
            }
        }

        public string Name
        {
            get
            {
                return this.screenObject.Name;
            }
        }

        public string DisplayName
        {
            get
            {
                return this.screenObject.DisplayName;
            }
            set
            {
                this.screenObject.DisplayName = value;
            }
        }

        public string Description
        {
            get
            {
                return this.screenObject.Description;
            }
            set
            {
                this.screenObject.Description = value;
            }
        }

        public bool CanSave
        {
            get
            {
                return this.screenObject.CanSave;
            }
        }

        public void Save()
        {
            this.screenObject.Save();
        }

        public void Refresh()
        {
            this.screenObject.Refresh();
        }

        public void Close(bool promptUserToSave)
        {
            this.screenObject.Close(promptUserToSave);
        }

        IBusinessDetails IBusinessObject.Details
        {
            get
            {
                return ((IBusinessObject)this.screenObject).Details;
            }
        }

        IStructuralDetails IStructuralObject.Details
        {
            get
            {
                return ((IStructuralObject)this.screenObject).Details;
            }
        }

        IDetails IObjectWithDetails.Details
        {
            get
            {
                return ((IObjectWithDetails)this.screenObject).Details;
            }
        }
    }
}

Add Silverlight Resource Dictionary TextBlockStyle

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Microsoft.LightSwitch.Presentation.Framework.Helpers;assembly=Microsoft.LightSwitch.Client">

    <Style x:Key="TextBlockFontsStyle" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="{StaticResource NormalFontFamily}" />
        <Setter Property="FontSize" Value="{StaticResource NormalFontSize}" />
        <Setter Property="FontWeight" Value="{StaticResource NormalFontWeight}" />
        <Setter Property="FontStyle" Value="{StaticResource NormalFontStyle}" />
    </Style>

</ResourceDictionary>

Add Converters.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace LocalizationLS.Presentation.Shells
{
    using Microsoft.LightSwitch;
    using Microsoft.LightSwitch.Details;
    using Microsoft.LightSwitch.Client;
    using Microsoft.LightSwitch.Details.Client;

    public class WorkspaceDirtyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }

    public class ScreenHasErrorsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }

    public class ScreenResultsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ValidationResults results = (ValidationResults)value;
            StringBuilder sb = new StringBuilder();

            foreach (ValidationResult result in results.Errors)
                sb.AppendLine(String.Format("Error: {0}", result.Message));

            return sb.ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }

    public class CurrentUserConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string currentUser = (string)value;

            if ((null == currentUser) || (0 == currentUser.Length))
                return "Authentication is not enabled.";

            return currentUser;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

Change LocalizationShell.Presentation.Shell.LSShell.cs

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\LightSwitch\Client\Microsoft.LightSwitch.ExportProvider.dll

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.VisualStudio.ExtensibilityHosting;
using Microsoft.LightSwitch.Sdk.Proxy;
using Microsoft.LightSwitch.Runtime.Shell;
using Microsoft.LightSwitch.Runtime.Shell.View;
using Microsoft.LightSwitch.Runtime.Shell.ViewModels.Commands;
using Microsoft.LightSwitch.Runtime.Shell.ViewModels.Navigation;
using Microsoft.LightSwitch.Runtime.Shell.ViewModels.Notifications;
using Microsoft.LightSwitch.BaseServices.Notifications;
using Microsoft.LightSwitch.Client;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Threading;
using Microsoft.LightSwitch.Details;


namespace LocalizationLS.Presentation.Shells
{
    public partial class LSShell : UserControl
    {
        private IServiceProxy serviceProxy;
        private List<object> weakHelperObjects = new List<object>();
        private DispatcherTimer doubleClickTimer;

        public LSShell()
        {
            this.InitializeComponent();

            // Use the notification service, found on the service proxy, to subscribe to the ScreenOpened,
            // ScreenClosed, and ScreenReloaded notifications.
            this.ServiceProxy.NotificationService.Subscribe(typeof(ScreenOpenedNotification), this.OnScreenOpened);
            this.ServiceProxy.NotificationService.Subscribe(typeof(ScreenClosedNotification), this.OnScreenClosed);
            this.ServiceProxy.NotificationService.Subscribe(typeof(ScreenReloadedNotification), this.OnScreenRefreshed);

            // Sign up for the Closing event on the user settings service so we can commit any settings changes.
            this.ServiceProxy.UserSettingsService.Closing += this.OnSettingsServiceClosing;

            // Read in the saved settings from the user settings service.  This shell saves the width of
            // the two columns that are separated by a grid splitter.
            double width1 = this.ServiceProxy.UserSettingsService.GetSetting<double>("RootColumn1_Size");
            double width2 = this.ServiceProxy.UserSettingsService.GetSetting<double>("RootColumn2_Size");

            // If the settings were successfully retrieved, then set the column widths accordingly.
            if (width1 != default(double))
                this.LayoutRoot.ColumnDefinitions[0].Width = new GridLength(width1, GridUnitType.Star);

            if (width2 != default(double))
                this.LayoutRoot.ColumnDefinitions[1].Width = new GridLength(width2, GridUnitType.Star);

            // Initialize the double-click timer, which is used for managing double clicks on an item in the tree view.
            this.doubleClickTimer = new DispatcherTimer();
            this.doubleClickTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
            this.doubleClickTimer.Tick += new EventHandler(this.OnDoubleClickTimerTick);
        }

        public void OnSettingsServiceClosing(object sender, EventArgs e)
        {
            // This function will get called when the settings service is closing, which happens
            // when the application is shut down.  In response to that event we will save the
            // current widths of the two columns.
            this.ServiceProxy.UserSettingsService.SetSetting("RootColumn1_Size", this.LayoutRoot.ColumnDefinitions[0].ActualWidth);
            this.ServiceProxy.UserSettingsService.SetSetting("RootColumn2_Size", this.LayoutRoot.ColumnDefinitions[1].ActualWidth);
        }

        public void OnScreenOpened(Notification n)
        {
            // This method is called when a screen has been opened by the run time.  In response to
            // this, we need to create a tab item and set its content to be the UI for the newly
            // opened screen.
            ScreenOpenedNotification screenOpenedNotification = (ScreenOpenedNotification)n;
            IScreenObject screenObject = screenOpenedNotification.Screen;
            IScreenView view = this.ServiceProxy.ScreenViewService.GetScreenView(screenObject);

            // Create a tab item and bind its header to the display name of the screen.
            TabItem ti = new TabItem();
            DataTemplate template = (DataTemplate)this.Resources["TabItemHeaderTemplate"];
            UIElement element = (UIElement)template.LoadContent();

            // The IScreenObject does not contain properties indicating if the screen has
            // changes or validation errors.  As such, we have created a thin wrapper around the
            // screen object that does expose this functionality.  This wrapper, a class called
            // MyScreenObject, is what we'll use as the data context for the tab item.
            ti.DataContext = new MyScreenObject(screenObject);
            ti.Header = element;
            ti.HeaderTemplate = template;
            ti.Content = view.RootUI;

            // Add the tab item to the tab control.
            this.ScreenArea.Items.Add(ti);
            this.ScreenArea.SelectedItem = ti;

            // Set the currently active screen in the active screens view model.
            this.ServiceProxy.ActiveScreensViewModel.Current = screenObject;
        }

        public void OnScreenClosed(Notification n)
        {
            // A screen has been closed and therefore removed from the application's
            // collection of active screens.  In response to this, we need to do
            // two things:
            //  1.  Remove the tab item that was displaying this screen.
            //  2.  Set the "current" screen to the screen that will be displayed
            //      in the tab item that will be made active.
            ScreenClosedNotification screenClosedNotification = (ScreenClosedNotification)n;
            IScreenObject screenObject = screenClosedNotification.Screen;

            foreach (TabItem ti in this.ScreenArea.Items)
            {
                // We need to get the real IScreenObject from the instance of the MyScreenObject.
                IScreenObject realScreenObject = ((MyScreenObject)ti.DataContext).RealScreenObject;

                if (realScreenObject == screenObject)
                {
                    this.ScreenArea.Items.Remove(ti);
                    break;
                }
            }

            // If there are any tab items left, set the current tab to the last one in the list
            // AND set the current screen to be the screen contained within that tab item.
            int count = this.ScreenArea.Items.Count;

            if (count > 0)
            {
                TabItem ti = (TabItem)this.ScreenArea.Items[count - 1];

                this.ScreenArea.SelectedItem = ti;
                this.ServiceProxy.ActiveScreensViewModel.Current = ((MyScreenObject)(ti.DataContext)).RealScreenObject;
            }
        }

        public void OnScreenRefreshed(Notification n)
        {
            // When a screen is refreshed, the run time actually creates a new IScreenObject
            // for it and discards the old one.  So in response to this notification, 
            // replace the data context for the tab item that contains
            // this screen with a wrapper (MyScreenObject) for the new IScreenObject instance.
            ScreenReloadedNotification srn = (ScreenReloadedNotification)n;

            foreach (TabItem ti in this.ScreenArea.Items)
            {
                IScreenObject realScreenObject = ((MyScreenObject)ti.DataContext).RealScreenObject;

                if (realScreenObject == srn.OriginalScreen)
                {
                    IScreenView view = this.ServiceProxy.ScreenViewService.GetScreenView(srn.NewScreen);

                    ti.Content = view.RootUI;
                    ti.DataContext = new MyScreenObject(srn.NewScreen);
                    break;
                }
            }
        }

        private IServiceProxy ServiceProxy
        {
            get
            {
                // Get the service proxy that provides access to the needed LightSwitch services.
                if (null == this.serviceProxy)
                    this.serviceProxy = VsExportProviderService.GetExportedValue<IServiceProxy>();

                return this.serviceProxy;
            }
        }

        private void GeneralCommandHandler(object sender, RoutedEventArgs e)
        {
            // This function will get called when the user clicks one of the buttons on
            // the command panel.  The sender is the button whose data context is the
            // IShellCommand.
            //
            // In order to execute the command (asynchronously) we simply call the
            // ExecuteAsync method on the ExecutableObject property of the command.
            IShellCommand command = (IShellCommand)((Button)sender).DataContext;

            command.ExecutableObject.ExecuteAsync();
        }

        private void OnTreeViewLoaded(object sender, RoutedEventArgs e)
        {
            this.ScreenTree.Dispatcher.BeginInvoke(() =>
            {
                TreeView tv = (TreeView)sender;

                foreach (object item in tv.Items)
                {
                    TreeViewItem tvi = tv.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;

                    tvi.IsExpanded = true;
                }
            });
        }

        private void OnTabItemSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // When the user selects a tab item, set the "active" screen
            // in the ActiveScreensView model.  Doing this causes the commands view
            // model to be udpated to reflect the commands of the current screen.
            if (e.AddedItems.Count > 0)
            {
                TabItem selectedItem = (TabItem)e.AddedItems[0];

                if (null != selectedItem)
                {
                    IScreenObject screenObject = ((MyScreenObject)selectedItem.DataContext).RealScreenObject;

                    this.ServiceProxy.ActiveScreensViewModel.Current = screenObject;
                }
            }
        }

        private void OnClickTabItemClose(object sender, RoutedEventArgs e)
        {
            // When the user closes a tab, we simply need to close the corresponding
            // screen object.  The only caveat here is that the call to the Close
            // method needs to happen on the logic thread for the screen.  To do this, 
            // use the Dispatcher object for the screen.
            IScreenObject screenObject = ((Button)sender).DataContext as IScreenObject;

            if (null != screenObject)
            {
                screenObject.Details.Dispatcher.EnsureInvoke(() =>
                {
                    screenObject.Close(true);
                });
            }
        }

        private void NavigationItemLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (this.doubleClickTimer.IsEnabled)
            {
                this.doubleClickTimer.Stop();

                // If the item clicked on is a screen item, then open the screen.
                INavigationScreen screen = ((TextBlock)sender).DataContext as INavigationScreen;

                if (null != screen)
                    screen.ExecutableObject.ExecuteAsync();
            }
            else
                this.doubleClickTimer.Start();
        }

        private void OnDoubleClickTimerTick(object sender, EventArgs e)
        {
            this.doubleClickTimer.Stop();
        }
    }
}

Añadir las referencias a LocalizationShell.Client

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\LightSwitch\Client\Microsoft.LightSwitch.ExportProvider.dll

C:\Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\Libraries\Client\System.Windows.Controls.dll

Build Project: Build succeeed 🙂

Step 5 of 10 Add Elements to LocalizationLS

Create table Persons

Create Screen (ListDetail)

Test Data

Step 6 of 10
Copy folder EventAgreggator from codelocalization.rar downloaded.

add References to:

Microsoft.Practices.Composite.dll
Microsoft.Practices.Composite.Presentation.dll

Step 7 of 10 IdiomasControl
Add a new User Control into Shell (LocalizationShell.Client) named IdiomasControl.

<UserControl x:Class="LocalizationLS.Presentation.Shells.IdiomasControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">

        <ComboBox Name="ComboBoxIdiomas" Grid.Column="0" Width="150" Height="80" SelectionChanged="ComboBoxIdiomas_SelectionChanged">
            <ComboBoxItem Content="English" IsSelected="True"/>
            <ComboBoxItem Content="Spanish"/>
            <ComboBoxItem Content="Catalán"/>
            <ComboBoxItem Content="French"/>
        </ComboBox>
    </Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Resources;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using EventAggregation;



namespace LocalizationLS.Presentation.Shells
{

    public partial class IdiomasControl : UserControl
    {
        IEventAggregator Aggregator = new EventAggregator();


        public IdiomasControl()
        {
            InitializeComponent();


        }

        private void ComboBoxIdiomas_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //Aggregator = new EventAggregator();

            System.Windows.Controls.ComboBox ComboBoxIdiomas = (System.Windows.Controls.ComboBox)sender;

            switch (ComboBoxIdiomas.Items.IndexOf(ComboBoxIdiomas.SelectedItem))
            {
                case 0: // English
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
                    Aggregator.SendMessage<MessageCambioIdioma, string>(new MessageCambioIdioma { Payload = "en-US" });

                    break;
                case 1: // Spanish
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("es");
                    Aggregator.SendMessage<MessageCambioIdioma, string>(new MessageCambioIdioma { Payload = "es" });
                    break;
                case 2: // Catalan
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ca-ES");
                    Aggregator.SendMessage<MessageCambioIdioma, string>(new MessageCambioIdioma { Payload = "ca-ES" });
                    break;
                case 3: // French
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr");
                    Aggregator.SendMessage<MessageCambioIdioma, string>(new MessageCambioIdioma { Payload = "fr" });
                    break;
                default:
                    break;
            }

        }
    }
}

Uncomment call to usercontrol IdiomasControl into LSShell.xaml

<!–<local:IdiomasControl Grid.Column=»2″ />–>

Step 8 of 10 Resource Files

Copy folder Localization from CodigoLocalizacion.rar downloaded into LocalizationLS.Client

Step 9 of 10 Make Changes in Application.cs

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;
using System.Resources;
using System.Threading;
using LightSwitchApplication.Localization;
using System.Globalization;
using System.Windows;
using EventAggregation;

namespace LightSwitchApplication
{

    public partial class Application
    {
        EventAggregation.IEventAggregator AggregatorCambiaPais { get; set; }

        public ResourceManager man;

        partial void Application_Initialize()
        {
            AggregatorCambiaPais = new EventAggregation.EventAggregator();
            AggregatorCambiaPais.Subscribe<MessageCambioIdioma, string>(OnMessageScreenCambioIdioma);

        }

        public void OnMessageScreenCambioIdioma(PresentationEvent<string> e)
        {
            char[] separator = { ',' };
            if ((string)e.Payload != null)
            {
                string[] PresentationParams = e.Payload.Split(separator);
                switch (PresentationParams[0])
                {
                    case "en-US":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_en_US", typeof(AppStrings_en_US).Assembly);
                        break;
                    case "ca-ES":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_ca_ES", typeof(AppStrings_ca_ES).Assembly);
                        break;
                    case "es":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_es", typeof(AppStrings_es).Assembly);
                        break;
                    case "fr":
                        man = new ResourceManager("LightSwitchApplication.Localization.AppStrings_fr", typeof(AppStrings_fr).Assembly);
                        break;
                    default:

                        break;
                }
            }
        }
    }
}

Step 10 of 10 Changes in PersonsSetListDetail.cs
The code I present here is clearly improved, but it is a good way to understand how it works, I walk the object tree recursively starting from RootContentItem, and I’m referring to the resource file.
This should be repeated in each Screen to locate.(clearly improved)

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;
using Microsoft.LightSwitch.Client;
using System.Text;
using System.Threading;
using System.Globalization;
using System.Reflection;
using System.Resources;


namespace LightSwitchApplication
{
    public partial class PersonsSetListDetail
    {

        partial void PersonsSetListDetail_Activated()
        {
            LocalizeScreenLS();
        }

        private void LocalizeScreenLS()
        {
            StringBuilder stringBuilder = new StringBuilder();
            IContentItemProxy proxy = this.FindControl("RootContentItem");
            proxy.ControlAvailable += (s, e) =>
            {
                var ctrl = e.Control as System.Windows.Controls.Control;
                IContentItem contentItem = ctrl.DataContext as Microsoft.LightSwitch.Presentation.IContentItem;
                LocalizeScreenControl(this, contentItem, stringBuilder);
            };
        }


        private void LocalizeScreenControl(IScreenObject screen, Microsoft.LightSwitch.Presentation.IContentItem item, StringBuilder stringBuilder)
        {
            var c = screen.FindControl(item.Name);
            if (c != null)
            {
                try
                {
                    item.DisplayName = this.Application.man.GetString(item.DisplayName, Thread.CurrentThread.CurrentUICulture);
                }
                catch (Exception)
                {
                    item.DisplayName = item.DisplayName;
                }
            }

            foreach (var i in item.ChildItems)
                LocalizeScreenControl(screen, i, stringBuilder);
        }

    }
}


English (en-US)

Spanish(es)

Catalan (ca-ES)

French (fr)

Known Issues.
I have found no way to access the pre-rendering of the display, so that the location of fields that occurs after the labels have been displayed with its original value, ie without trace, this produces an effect somewhat strange when viewing the form, if someone comes up with something would be great.

A turn around can be awkward to leave blank the display name (with a space) and write the label to locate in the description, change the location code for this then appear first form with empty fields and then routine rewrite the screen with the correct titles.

Discussions
LightSwitch is a great tool, and with a little work can make to get to anywhere, I hope Microsoft solves this feature as soon as possible, because in a globalized world is almost basic. I hope this article will encourage everyone to look for alternatives and especially better, thing I am totally safe and that encourages me recursively.

Acknowledgements
Special thanks to all the LightSwitch community. Also thanks to the review of this article realized by Ramón Barrena.

You can test the result of how-to on: http://www.jmlabs.org.es/localizationls

Layout Dashboard Screen LightSwitch

Esta entrada del blog es útil cuando queremos formatear rápidamente una pantalla «vacía» de LighSwitch para utilizarla como «Home» o «Dashboard» para nuestra aplicación.

El objetivo, una imagen vale más que mil palabras:

La pantalla se divide en dos zonas horizontales, las marco en el dibujo para que se vean bien:

Tabs Layout: Corresponde a la zona 1
TableColumnLayout: Corresponde a la zona 2

Group

Dentro del Table Layout tenemos una columna (TableColumn Layout), en esta columna colocamos tres campos Text que corresponden al título del la zona 1.

Group 2

Consta de dos controles un control tab y una columna.

La Tab contiene 4 table layout (1 por cada icono que vemos en la imagen de como queda el conjunto), acordarse de darle un tamaño de anchura al tab sino repartirá proporcionalmente el tab y la columna.

Espero que sirva como punto inicial para personalizar aplicaciones LighSwitch!

c# 2012 Visual Studio Programación asincrona con Async y Await

Uno de los mejores remedios para  evitar los cuellos de botella y mejorar la capacidad de respuesta global de la aplicación mediante programación asíncrona. Sin embargo, las técnicas tradicionales para la creación de aplicaciones asíncronas pueden ser complicadas, lo cual es difícil de escribir, depurar y mantener.

Visual Studio 2012 presenta un enfoque simplificado, programación asíncrona, que aprovecha el apoyo asincrónico en el Marco. NET 4.5 y el tiempo de ejecución de Windows. El compilador hace el trabajo difícil que el desarrollador utiliza para hacer, y su aplicación conserva una estructura lógica que se asemeja código sincrónico. Como resultado, se  obtienen todas las ventajas de la programación asíncrona con una fracción del esfuerzo.

ASYNC mejora la respuesta.

La asincronía es esencial para las actividades que son potencialmente bloqueo, como cuando su aplicación tiene acceso a la web. El acceso a un recurso web a veces es lenta o retardada. Si tal actividad está bloqueada dentro de un proceso síncrono, toda la aplicación debe esperar. En un proceso asíncrono, la aplicación puede continuar con otro trabajo que no depende de los recursos web hasta que finalice la tarea potencialmente bloqueo.

Asincronía resulta especialmente útil para aplicaciones que acceden al hilo de interfaz de usuario porque toda la actividad relacionada con la interfaz de usuario suele compartir un hilo. Si cualquier proceso está bloqueado en una aplicación sincrónica, todos están bloqueados. Su aplicación deja de responder y se podría concluir que no ha lugar cuando se está esperando.

Al utilizar los métodos asincrónicos, la aplicación sigue respondiendo a la interfaz de usuario. Puede cambiar el tamaño o minimizar una ventana, por ejemplo, o puede cerrar la aplicación si no quieres esperar a que termine.

El enfoque asincrónico basado en la suma equivalente a una transmisión automática a la lista de opciones que se pueden elegir a la hora de diseñar las operaciones asincrónicas. Es decir, usted obtiene todos los beneficios de la programación asincrónica tradicional, pero con mucho menos esfuerzo del promotor.

El Async y Await las keywords de Visual Basic y el async y await las keywords clave de C # son el corazón de la programación asíncrona. Mediante el uso de estas dos palabras clave, puede utilizar los recursos en el Marco. NET o el tiempo de ejecución de Windows para crear un método asincrónico casi tan fácilmente como se crea un método sincrónico. Métodos asincrónicos que se definen con async y esperan se les conoce como los métodos asincrónicos.

Fuente: Microsoft MSDN

VS2010 Crash cuando abre ficheros XAML

Hoy me ha ocurrido una incidencia que me ha llevado un buen rato resolver, Visual Studio ha comenzado al colgarse al abrir ficheros XAML, después de desinstalar VS2010, Silverlight4 tools para VS, RIA SERVICES y todo lo que podía pensar que podía fallar el problema seguía persistiendo, gracias a los chicos de silverlight.net que han aportado una solución que en mi caso a funcionado. http://forums.silverlight.net/t/234697.aspx/1, el tema era desisntalar de la GAC el archivo system.windows.dll.

Espero que os sea de ayuda…

 

Error al abrir diagramas de bases de datos en SQL SERVER.

Cuando estamos desarrollando, es frecuente que traslademos la base de datos de un servidor SQL a otro, no voy a hablar de esto sino de lo que ocurre cuando intentamos abrir los diagramas de bases de datos, ya que nos podemos encontrar con el siguiente mensaje:

En realidad esto no es un error sino un aviso informativo de que el propietario no es el mismo que creo la base de datos, simplemente abrir una nueva consulta con conexión actual desde el menu y escribir:

ALTER AUTHORIZATION ON DATABASE::miDatabase TO valid_login

Ejecutar y esto es todo.

 

SQL Server Profiler Supervisar instáncia base de datos

En este artículo haré un breve resumen de la utilización de SQL SERVER Profiler, herramienta de indudable interés para saber que está ocurriendo en nuestra base de datos.

Lo primero que haremos será localizarlo en la lista de programas, microsoft sql server 2008, Perfomance Tools, SQL SERVER PROFILER

profiler joan miquel fernandez jmdeveloper

También podemos acceder a él desde el Management Studio
profiler joan miquel fernandez jmdeveloper

Esperamos a que arranque

profiler joan miquel fernandez jmdeveloper

Creamos una nueva traza

profiler joan miquel fernandez jmdeveloper

Nos conectamos a la instancia de la base de datos

profiler joan miquel fernandez jmdeveloper

Aquí podemos elegir entre varias templates

profiler joan miquel fernandez jmdeveloper

Podemos configurar los diferentes eventos a monitorizar, por defecto  y para pruebas no hace falta cambiar nada.
profiler joan miquel fernandez jmdeveloper

Vemos un ejemplo de como aplicar un filtro

profiler joan miquel fernandez jmdeveloper


profiler joan miquel fernandez jmdeveloper

Aquí vemos como vamos recibiendo las diferentes operaciones dentro de la traza.
profiler joan miquel fernandez jmdeveloper

Espero que os sea de utilidad… 🙂

Imprimir con LightSwitch y ActiveReports6 (y III)

En esta tercera y última parte llegamos al final del artículo y Joan Miquel Fernandez termina mostrandonos como crear el formato de impresión y su uso en el Visor (Viewer) SilverLight de ActiveReports6 dentro de aplicaciones LightSwitch.
Comenzamos cambiando el modelo de vista del proyecto. De Logical View a File View.
En el proyecto Cliente añadimos un nuevo Item.
De tipo Active Reports 6 (Xml File) y lo llamamos report.rpx
Abrimos el fichero con Visual Studio, ya está listo para trabajar con él.
Clicamos en el Elemento Detail (clicar en el icono)
Seleccionamos la pestaña SQL y construimos la ConnectionString
Dejo un ejemplo de la ConnectionString que he utilizado, si teneis alguna duda de como se construye podeis consultar en http://www.connectionstrings.com/

 data source=.\SQLExpress;initial catalog=series;persist security info=False;user id=test;password=1234;
De todas maneras con la opción Build, la podeis construir.
Detalle de la conexión
Introducimos la query: Select * from ventas
Mediante el modo Preview podemos ir cambiando a la previsualización y con el modo Design a diseño.

Desde View/Toolbars de Visual Studio mostramos el Report Explorer 6 y arrastramos los campos al report.

Mediante el modo Preview podemos ir cambiando a la previsualización y con el modo Design a diseño.
Accedemos al proyecto ServerGenerated
Modificamos el webconfig y añadirmos los httphandlers para los rpx
 < add verb="*" path="*.rpx" type="DataDynamics.ActiveReports.Web.Handlers.RpxHandler, ActiveReports.Web, Version=6.2.3164.0,Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
Para utilizar el rpx tenemos que copiarlo en la carpeta donde se ejecute el programa
..\TestLightSwitchAR6\TestLightSwitchAR6\Client
Accedemos al proyecto cliente y copiamos el report.rpx
Lo copiamos en la carpeta debug, ojo que en Client también hay otra carpeta bin\debug ;O
TestLightSwitchAR6\TestLightSwitchAR6\Bin\Debug
Cuando ejecutemos el visor ya podemos acceder al informe report.rpx que hemos creado.
¿Qué viene ahora? – En este tutorial hemos visto el trabajo básico con el rpx. Como habeis visto no es un ejemplo funcional sino que explica que cosas hay que hacer para poder abrir un rpx desde LS. También deja sin explicar como seleccionar un grupo de registros en concreto, eso será parte del próximo tutorial, ha quedado fuera de este para no generar excesiva complejidad.
Los archivos para descarga están disponibles aquí.

http://cid-7968f234f468d7a5.office.live.com/embedicon.aspx/.Public/TestLightSwitchAR6

Imprimir con LightSwitch y ActiveReports6 (II)

En esta segunda parte Joan Miquel Fernandez continua mostrandonos la manera para añadir el Visor (Viewer) SilverLight de ActiveReports6 dentro de aplicaciones LightSwitch.

En este momento el objetivo es añadir un nuevo proyecto que aloja en su interior el user control que vamos a utilizar.

 
Con un poco de imaginación lo llamamos SilverlightARViewer 🙂

Es un proyecto tipo Silverlight 4, cuanto más se aprenda de Silverlight 4 y WPF más partido se obtiene de LS.

 

Eliminamos la clase que crea el asistente ya que en nuestro caso no nos sirve.

 
Es el momento de añadir el user Control

Sigamos en modo creativo y lo llamaremos SilverlightControlViewer

 
Añadimos la referencia a AR6 Viewer.

 
Esta es la referencia a añadir…

 

Ya podemos arrastrar y soltar el visor en nuestro control.


 

Creamos el Evento Loaded y añadimos un poco de código tal y como está en la imágen.

 private void viewer1_Loaded(object sender, RoutedEventArgs e)
        {
            var relPath = new Uri("../report.rpx?OutputFormat=Rdf3", UriKind.RelativeOrAbsolute);
            viewer1.ViewModel.LoadDocument.Execute(relPath);
        }

 

Build…

 

Todo ok.

 

Añadimos una nueva Screen…

 

La llamamos Visor Informe

 

Añadimos un Custom Control

 

Buscamos la referencia al proyecto que hemos creado

 

Y lo asociamos a nuestro Control

 

Aquí lo tenemos, de momento no tiene ningún informe asociado…

 

¿Qué viene ahora? – En el siguiente tutorial veremos de como crear un formato de impresión y asociarlo con la base de datos.

Los archivos para descarga estarán en la última parte del tutorial…