Thread.CurrentPrincipal

El Client Application Services que podem implementar a la nostre aplicació WPF ens permet validar a un usuari d’una manera molt senzilla. Aquesta validació es guarda a una propietat CurrentPrincipal del thread. El problema és que la autentificació es guarda al thread que ha provocat la verificació. Però què passa quan es creen threads secundaris? Per internet hi ha articles que es diu que els threads secundaris hereden el CurrentPrincipal del Thread principal però no ho he provat, el que si que he provat és que els threads creats per la crida de funcions asíncrones per Beginxxxx no hereden aquesta propietat. El problema que hi ha és que si llavors executem alguna crida a algun servei web aquest no està amb autentificació.

Una de les solucions que ens podem buscar és la d’utlitzar el mètode SetThreadPrincipal de la classe AppDomain. Aquest mètode serveix per indicar quin és el CurrentPrincipal per defecte que tindran tots els threads del domini. És correcte i útil però té el problema que només es pot assignar una sola vegada. Quan es vol assignar una segona vegada provoca una excepció PolicyException, per tant, per els escenaris on es fa login/logout per després poder fer un altre login no ens serveix.

try
{
AppDomain.CurrentDomain.SetThreadPrincipal(Thread.CurrentPrincipal);
}
catch (System.Security.Policy.PolicyException) { }

Indagant per el .Net no m’ha quedat una altre alternativa que crear una classe estàtica ApplicationContext on per una propietat CurrentPrincipal l’hi assigno el IPrincipal que tinc en cada moment que es fa el login.

Anuncis

WPF : Commands II

Continuo parlant dels Commands. A la primera part he parlat del model Command de WPF i de l’ús dels estàndards. Ara parlaré de com crear els nostres propis commands.

RoutedCommand i RoutedUICommand son dues clases base que implementen la interface ICommand i per tant les podem utilitzar per crear els nostres propis commands. Per fer-ho declarem com a estàtiques variables d’aquests tipus i seguim amb el mateix model que vam explicar a la primera part.

public static RoutedUICommand myRoutedUICommand = new RoutedUICommand("El mey routed command","El_mey_routed_command", typeof(MainWindow));

En aquesta declaració utilitzem en RoutedUICommand perquè ens permet indicar el text que es visualitzarà a la opció del menú. El constructor pot tenir un quart paràmetre que serà la combinació de tecles a utilitzar per poder executar l’acció.

Ara ja podem crear l’enllaç

<CommandBinding Command="{x:Static local:MainWindow.myRoutedUICommand}" Executed="CommandBinding_Executed_2"></CommandBinding>

L’assignem a una opció de menú

<MenuItem Command="{x:Static local:MainWindow.myRoutedUICommand}"></MenuItem>

I fem la seva implementació

private void CommandBinding_Executed_2(object sender, ExecutedRoutedEventArgs e)
{
//Implementar l'acció
}

WPF : Commands

Una de les novetats que hi ha a WPF és la dels Commands. Els commands és una manera de poder executar operacions des de qualsevol control que generi events: una opció del menú, de la barra d’eines, d’un menú contextual o d’un simple botó. En Winforms cada un d’aquests controls genera un event (generalment el click) i hem de fer que cada un d’ells executi les acciones corresponents. Però què passa quan la mateixa acció s’executa des de diferents parts de la pantalla? Doncs que per cada un dels events hem d’executar la mateixa acció.

Amb WPF tenim també aquesta possibilitat, els events continuen exisitint encara que ara s’anomenen RoutedEvents, però tenim una manera més senzilla de fer que diferents controls de la pantalla executin la mateixa acció: utilitzant la propietat Command. Aquesta propietat ja és utilitzada en ASP.NET i per tant per els que heu treballat amb ASP.NET ja us sona millor. La unica cosa que hem de tenir present és que es diferencia molt amb la manera d’implementar-ho.

La interface ICommand. Aquesta és la interface que implementen tots els command que tenim a WPF. Amb WPF tenim una llibreria implementada de commands: ApplicationCommands, NavigationCommands, EditingCommands, ComponentCommands i MediaCommands.

public interface ICommand
{
void Execute(object parameter);
bool CanExecute(object parameter);
event EventHandler CanExecuteChanged;
}

RoutedCommand. És una clase base que implementa ICommand.

RoutedUICommand. És una clase base que implementa ICommand i afegeix una propietat Text que és el que es visualitzarà al control. Per tant és el que utilitzem en els controls de la pantalla.

El model Command

Commands: Un Command representa una acció a realitzar

Command Binding: Enllaç del command a als mètodes que implementen els events: Executed i CanExecuted

Command Source: Control que llença el command (opció de menú o botó)

Command Target: Control on l’acció es realitzarà.

Per veure-ho millor anem a aplicar un exemple amb el Command Open.

<MenuItem Header="File">
<MenuItem Command="Open"></MenuItem>
</MenuItem>

El menú que genera és el següent:

Està desactivat perquè ens falta indicar com implementarem l’acció, per això creem l’enllaç

<Window.CommandBindings>
<CommandBinding Command="Open" Executed="CommandBinding_Executed"></CommandBinding>
</Window.CommandBindings>

La implementació

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
//Implementem l'acció a realitzar
}

A la segona part parlo dels RoutedUICommand

Silverlight Toolkit: Expander per sobre d’un Grid

Un dels problemes més comuns quan estem maquetant webs és que una capa (div) estigui per sobre o per sota d’una altre element de la pàgina en el moment que la fem visible. Per solucionar-ho utilitzem z-index per marcar quin element va per sobre d’un altre.

A Silverlight no tenim aquesta propietat en tots els elements, si que hi és al Canvas. Quan utilitzem el control Expander que hi ha al Silverlight Toolkit el més comú és que la capa que s’obre no es pugui visualitzar correctament tota ja que sobrepassa els límits marcats per les files del Grid.

Per aconseguir que els elements que es visualitzen quan es desplega l’expander estiguin per sobre dels altres elements hem d’utilitzar el control Popup. Capturant els events Collapsed i Expanded del control Expander fem la feina d’obrir i tancar el popup.

<toolkit:Expander Name="expander1" Width="209" Header="Benvingut {0}" Expanded="expander1_Expanded" Collapsed="expander1_Collapsed">
<Popup Name="pop" >

   <StackPanel Width="209" x:Name="LinksStackPanelVertical" Orientation="Vertical" HorizontalAlignment="Right" >
<HyperlinkButton x:Name="perfilLink" Style="{StaticResource LinkStyle}"
NavigateUri="/account/perfil.aspx" TargetName="" Content="Perfil"/>
<HyperlinkButton x:Name="sortirLink" Style="{StaticResource LinkStyle}"
NavigateUri="/account/perfil.aspx" TargetName="" Content="Sortir"/>
</StackPanel>

  </Popup>
</toolkit:Expander>

private void expander1_Expanded(object sender, RoutedEventArgs e)
{
pop.IsOpen = true;
}


private void expander1_Collapsed(object sender, RoutedEventArgs e)
{
pop.IsOpen = false;
}

Segon trimestre de l’any

Durant aquest segon trimestre he impartit 5 cursos: 3 d’ASP.NET, 1 de WPF i 1 d’ASP.NET MVC.

Els d’ASP.NET cada un amb un nivell d’exigència diferent. El que en puc destacar és un que he fet per Anuntis. Una empresa amb més de 3 portals programats en ASP.NET. Un grup de 15 persones a punt per escoltar què els hi podia ensenyar de nou. El curs era d’ASP.NET amb el Visual Studio 2010 i per tant la única cosa que els hi podia ensenyar era les novetat dels Framework 4.o, però no té perquè ser així. El grup era avançat però hi havien conceptes d’ASP.NET en general que no tenien massa clar o que no havien fet mai. El primer dia serveix per el formador per estudiar els alumnes i veure quines son les coses que més els hi poden interessar per tal de que el temps que hi dediquen ells al curs els hi sigui el màxim d’útil.

De WPF era més orientat al databinding, a la gestió de la memòria i al rendiment.

El d’ASP.NET MVC és sobre la versió actual i nova: 3. Aquesta tecnologia és totalment diferent a ASP.NET amb Webforms. Penso que és interessant coneixa-ho i posar-ho a la pràctica és sempre segons els requeriments que tenim.

El meu projecte personal espero poder-ne parlar amb el resum del tercer trimestre.