Visualizzazione post con etichetta Silverlight. Mostra tutti i post
Visualizzazione post con etichetta Silverlight. Mostra tutti i post

lunedì 28 novembre 2011

Silverlight - Simulazione navigazione dati (stile Access)

Silverlight 4.0

Nella mia applicazione avevo la necessità di navigare tra i dati di una child window, stile Access tanto per intenderci.

Questa la view in questione, che ha il compito di gestire i Cespiti in carico.



Al loaded della view viene eseguito il binding dell’oggetto Cespite recuperato tramite un servizio WCF RIA Service. Nel mio caso il DocumentContext è il contesto al servizio che gestisce tutto il documento: ritenute d’acconto, ratei/risconti e cespiti compresi.
readonly DocumentoContext _documentoContext;

Cespite cespite = _documento.Cespite.Count > 0 ? _documento.Cespite.FirstOrDefault()
                                                : new Cespite();

if (_documento.Cespite.Count == 0)
   _documento.Cespite.Add(cespite);

LayoutRoot.DataContext = cespite;

A seconda se ne esistono già viene caricato il primo della lista o ne viene creato uno nuovo (in questo modo poi possiamo fare a meno del pulsante Nuovo nella toolbar).
Per passare quindi al cespite successivo o crearne uno di nuovo basta premere il pulsante con la freccia verso destra, al quale è associato il seguente evento:

private void NextCespiteClicked(object sender, MouseButtonEventArgs e)
{
      _index += 1;

      if (_index > _documentoContext.Cespites.Count - 1)
      {
          // Non ci sono cespiti, ne viene aggiunto quindi uno al contesto.
          Cespite cespite = new Cespite();
          _documento.Cespite.Add(cespite);

         // Binding del cespite appena creato alla view
         LayoutRoot.DataContext = cespite;
     }
     Else
         // Viene eseguito il binding del cespite dell'indice corrispondente.
         LayoutRoot.DataContext = _documentoContext.Cespites.ElementAt(_index);
}

Invece per andare all’elemento precedente basta premere il pulsante con la freccia verso sinistra al quale è associate il seguente evento:

private void PreviousCespiteClicked(object sender, MouseButtonEventArgs e)
{        
     if(_index >= 1)
     {
          _index -= 1;
          LayoutRoot.DataContext = _documentoContext.Cespites.ElementAt(_index);
     }
}

Chiaramente è un meccanismo alquanto semplice, abbastanza efficace, che può essere esteso a proprio piacimento.

mercoledì 24 agosto 2011

Silverlight - Tooltip su dei giorni particolari di un controllo Calendar

Silverlight 4.0

L’esigenza è quella ottenere un tooltip su alcuni giorni particolari, evidenziati in rosso, di un oggetto Calendar, ad esempio per evidenziare le proprie scadenze fiscali; e questa è la soluzione che ho adottato.
Come prima cosa ho creato i seguenti converter, uno per i giorni in “rosso” e l’altro per il tooltip:

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

namespace ContabilitaSelfService.Converter
{
    public class BackgroundDayCalendarConverter : IValueConverter
    {
        //public static IList<DateTime> Holidays { get; set; }
        public static IList<DateTime> Evidences { get; set; }

        public object Convert(object value,
                            Type targetType,
                            object parameter,
                            CultureInfo culture)
        {
            DateTime date = (DateTime)value;

            if (Evidences != null && Evidences.Contains(date))
                return new SolidColorBrush(Colors.Red);
            else if (date.Date == DateTime.Now.Date)
                return new SolidColorBrush(Colors.LightGray);
            else
                return new SolidColorBrush(Colors.Transparent);
        }

        public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;

namespace ContabilitaSelfService.Converter
{
    public class TooltipDayCalendarConverter : IValueConverter
    {
        public static IDictionary<DateTime, string> Tooltips { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;

            if (Tooltips != null && Tooltips.ContainsKey(date))
                return Tooltips[date];

            return null;
        }


        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}

Ho creato poi in un’ottica di riusabilità il seguente user control
<UserControl x:Class="ContabilitaSelfService.UserControls.DeskTop"

    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"

    xmlns:prim="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls"

    xmlns:src="clr-namespace:ContabilitaSelfService.Converter" xmlns:sdk="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" mc:Ignorable="d"

    d:DesignHeight="500" d:DesignWidth="180">

    <UserControl.Resources>

        <src:BackgroundDayCalendarConverter x:Key="BackgroundDayCalendarConverter" />

        <src:TooltipDayCalendarConverter x:Key="TooltipDayCalendarConverter" />

        <Style x:Key="CalendarDayButtonStyle1" TargetType="prim:CalendarDayButton">

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="prim:CalendarDayButton">

                        <Grid Background="{Binding Converter={StaticResource BackgroundDayCalendarConverter}, Path=Date}"

                              ToolTipService.ToolTip="{Binding Converter={StaticResource TooltipDayCalendarConverter}, Path=Date}">

                            <ContentControl x:Name="Content" Margin="5,1,5,1" Content="{TemplateBinding Content}" />

                        </Grid>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:Calendar HorizontalAlignment="Right" CalendarDayButtonStyle="{StaticResource CalendarDayButtonStyle1}" >
        </sdk:Calendar>
    </Grid>
</UserControl>

Da notare la parte di binding relativa ai converter.
A questo punto ho caricato le collection interne Evidences e Tooltips prendendo le informazioni da una tabella, nella quale sono state memorizzate tutte le mie scadenze. Tralasciando la parte di recupero dei dati, questa è la procedura per il caricamento delle scadenze:

private void LoadScadenzeCallBack(LoadOperation<Scadenzario> obj)
        {
            BackgroundDayCalendarConverter.Evidences = new List<DateTime>();
            TooltipDayCalendarConverter.Tooltips = new Dictionary<DateTime, string>();

            foreach (var scadenza in _context.Scadenzarios)
            {
                BackgroundDayCalendarConverter.Evidences.Add(scadenza.DataScadenza);
                TooltipDayCalendarConverter.Tooltips.Add(scadenza.DataScadenza, scadenza.Descrizione);  
            }           
        }

Nel mio caso, questo è il risultato finale:







martedì 23 agosto 2011

Silverlight 4.0 - WCF RIA Services - Enterprise Logging Application Block

SO Windows 7 a 64 bit - IIS 7.5 - VS2010 service pack1

Avevo questo tipo di problematica:

"Nella mia Silverlight Business Application ho implementato il Logging Application Block con l’estensione per Silverlight come da documentazione e tutto funziona correttamente, riesco a scrivere nel mio file di log tutte le informazioni che voglio, ma il fatto è che funziona solo se eseguo l’applicazione in emulazione, cioè con l’option “Usa Visual Studio Development Server”, se invece eseguo sempre da VS con “Usa server Web IIS Locale” l’applicazione non mi logga più niente. Credo sia un problema di permessi, però io ho dato i permessi alla cartella a tutto il mondo; ho cambiato anche l’identità di pool, impostandola a Nework Service, perché ho letto in un blog che WCF gira con Network Service, ma … niente da fare! E non so più dove sbattere la testa ... Naturalmente nell'event log di Windows non c'è nessun errore. A questo punto, qualsiasi altro suggerimento è bene accetto! Grazie mille!"

Alla fine ho trovato il motivo di tale anomalia.

Grazie Fiddler2!
Come capita spesso in questi casi, era una "baggianata"; in pratica era sbagliato l'endpoint del servizio WCF dell'applicazione Silverlight.
Era impostato nel seguente modo:

<endpoint address="/LoggingService.svc" ...

deve essere invece

<endpoint address="/MiaApplicazione.Web/LoggingService.svc" ...

Che sudata però ;-)

venerdì 19 agosto 2011

Silverlight - Close a ChildWindow

C# 4.0

Per chiudere una Child Window era stato impostato il seguente codice nell’evento di chiusura della view

private void WindowChild1_Close (object sender, MouseButtonEventArgs e)
        {
            DialogResult = true;
            Close();
        }
 
Questo però comportava che dopo un paio di chiusure della suddetta child l’intera applicazione era come fosse “disabilitata”, non si riusciva più ad interagire con il browser.

Ad oggi quindi per risolvere tale anomalia è stata aggiunta la seguente riga di codice:
 
Application.Current.RootVisual.SetValue(IsEnabledProperty, true);

L’evento è stato conseguentemente modificato nel seguente modo:

private void WindowChild1_Close (object sender, MouseButtonEventArgs e)
        {
            // Workaround to correctly close a child window
            Application.Current.RootVisual.SetValue(IsEnabledProperty, true);

            DialogResult = true;
            Close();
        }

… e così funziona!

martedì 9 agosto 2011

Silverlight 4.0 & IIS 7.5

Silverlight 4.0 (C#) & IIS 7.5

Pubblicando una Silverlight Business Application su IIS e richiamando la pagina di default dell’applicazione stessa http://localhost/BusinessApplication.Web/#/Home si ottiene il seguente messaggio d’errore: "Operazione Load non riuscita per la query 'GetUser'. Errore del server remoto: NotFound."



Il suddetto errore è stato risolto disabilitando l’autenticazione Windows su IIS.