Welcome

This is the generic homepage (aka Aggregate Blog) for a Subtext community website. It aggregates posts from every blog installed in this server. To modify this page, look for the Aggregate skin folder in the Skins directory.

To learn more about the application, check out the Subtext Project Website.

Powered By:
spacer

Syndication

Blog Stats

Bloggers (posts, last update)

Latest Posts

INotifyPropertyChanged serve davvero? Sì! Ma le cose si fanno complicate…

Leggendo per caso il blog di Gianni Giaccaglini (blogs.wpfitalia.it/GianniGiaccaglini/archive/2011/09/08/Binding-ADO-tramite-classe-ad-hoc.aspx) riguardo il binding verso dataset, ho notato un capitolo, “INotifyPropertyChanged server davvero?” e mi sono ricordato di un problema simile (forse lo stesso) che mi è capitato tempo fa.
Iniziamo dal codice xaml e il datacontext:

<StackPanel>
    <TextBox Text="{Binding Path=PrimaProp}" />
    <TextBox Text="{Binding Path=PrimaProp}" />
    <TextBox Text="{Binding Path=SecondaProp}" />
    <TextBox Text="{Binding Path=SecondaProp}" />
    <Button Content="Cambia" Click="Button_Click" />
</StackPanel>
public class MyDataContext
{
    public string PrimaProp { get; set; }
    public string SecondaProp { get; set; }
}

Qualcuno noterà che MyDataContext (nel codebehind viene impostata un istanza come DataContext) non implementa INotifyPropertyChanged.
Modificando una textbox ci si aspetterebbe che le altre non cambino perchè non si notifica alla vista che la proprietà è stata cambiata… E invece tutto funziona!
Ai tempi pensai che l’engine di wpf fosse abbastanza intelligente da usare un oggetto binding uguale se viene scritto uguale in più parti… invece no spacer .
Se proviamo infatti a impostare via codice il binding (es: textbox1.SetBinding(TextBox.TextProperty, new Binding(“PrimaProp”))), con nuove istanze di Binding su diversi oggetti, continua ancora a funzionare.

Proviamo a cambiare la proprietà del datacontext da codice tramite il bottone con:
(this.DataContext as MyDataContext).SecondaProp=”modifica da codice”… NON FUNZIONA!

Non sapendo dove andare a parare, ho cercato con google, e infine ho trovato la soluzione indicata qui: social.msdn.microsoft.com/Forums/en-US/wpf/thread/9365bb6a-b411-4967-9a03-ae2a810fb215/

Sunto della soluzione:
- Se un oggetto CLR implementa INotifyPropertyChanged, è cura del developer lanciare l’evento NotifyPropertyChanged
- Se un oggetto CLR NON implementa INotifyPropertyChanged, il binding lavora sul TypeDescriptor dell’oggetto. Esso va a registrare alla modifica delle proprietà tramite PropertyDescriptor.AddValueChanged().

Quindi:
1) come far andare il codice precedente riguardo il bottone:
”semplice” (?!?) basta recuperare la PropertyDescriptor dell’oggetto e impostare così la proprietà:
var propertyDescriptor = TypeDescriptor.GetProperties(this.DataContext).Find("SecondaProp", false);
propertyDescriptor.SetValue(this.DataContext, "ModificaDaCodice");

2) come far smettere di andare il precedente esempio:
Implementiamo l’interfaccia INotifyPropertyChanged e propaghiamo l’evento solo per PrimaProp. Questa funziona, ma SecondaProp no spacer .

Performance (mentre l’ho fatto ho sentito l’esigenza di un altro post)

Se eseguo il codice nel thread UI, le performance sono molto simili.
Se eseguo il codice in un altro thread, l’utilizzo di INotifyPropertyChanged risulta più rapido rispetto a PropertyDescriptor.

Conclusioni:

Data la flessibilità e la maggior facilità implementativa, la mia preferenza ricade indubbiamente a INotifyPropertyChanged. Le performance inoltre sembrerebbero avvalorare tale scelta. Quindi Me.NofifyPropertyChanged(“you”);

posted @ 9/10/2011 11:47 PM by Roberto Sarati

Silverlight 5 RC

Un po’ in sordina, è stata annunciata la Release Candidate di Silverlight 5 che potete scaricare da qui.
Questa versione è rivolta sostanzialmente agli sviluppatori e non supporta la licenza go-live, pertanto niente produzione per le nuove applicazioni.

Silverlight 5 RC now available

posted @ 9/1/2011 9:57 PM by Antonio Catucci

Binding del controllo Slider in Silverlight4

Oggi mi sono imbattuto in questo fastidioso problema: avete mai usato uno slider? se sì, avete mai messo in Binding le dependency property Minimum e Maximum oltre che a Value? vi è andato al primo colpo? fortunati …

Il problema principale è l’ordine con cui si imposta. In ordine si dovranno impostare i binding per:

  • Maximum
  • Minimum
  • Value

Se così non fate, Silverlight si perde qualcosa per strada spacer . Una corretta dichiarazione è quindi:

<Slider Maximum="{Binding Path=Max}" Minimum="{Binding Path=Min}" Value="{Binding Path=Value, Mode=TwoWay}" />

 

Se, come me, provate a impostare prima Minimum e poi Maximum, noterete che il valore di Maximum non viene impostato (anzi, se debuggate Maximum verrà impostato a zero).

Spero non perdiate tutto il tempo che io ho perso per capire il problema.

ps: in WPF4 è order independent.

posted @ 8/9/2011 12:57 AM by Roberto Sarati

Visual Studio LightSwitch 2011 RTM

Disponibile dal 26 luglio 2011 la RTM di Visual Studio LightSwitch 2011!
Il download è disponibile per tutti gli abbonati MSDN mentre per il pubblico sarà disponibile a partire da giovedì 28 luglio. Ricordiamo che Visual Studio LightSwitch sarà disponibile solo a pagamento ed è disponibile in alternativa una versione trial di 90 giorni.

Inoltre, Visual Studio LightSwitch 2011 è disponibile sin da subito anche in versione localizzata in italiano!

Sul blog ufficiale del team di LightSwitch trovate tutti i link alle risorse dedicate al prodotto per iniziare sin da subito a sviluppare le vostre applicazioni.

Infine, vi ricordo che oggi, a partire dalle 18:00, ci sarà l'evento online speciale dedicato al rilascio di LightSwitch. Se non lo avete ancora fatto, potete registrarvi all'indirizzo www.lightswitch.it/EventoLancioMicrosoftLightSwitch2011.aspx.

Vi aspettiamo!

posted @ 7/27/2011 9:54 AM by Antonio Catucci

Evento on line con LightSwitch Tips &amp; Tricks

Se siete interessati a Microsoft LightSwitch e volete saperne di più su come collegarsi a diverse fonti dati, potete seguire un webcast live sul sito LightSwitch Tips & Tricks, lunedì 20 giugno 2011, dalle 21:00 alle 22:00:

Utilizzare Visual Studio LightSwitch con fonti dati esistenti, tra SQL Server, Azure e SharePoint
con Alessandro Del Sole (Microsoft MVP)

“In questo Live Meeting verrà dimostrato come utilizzare database SQL Server esistenti in LightSwitch, incluso l'utilizzo di stored procedure, e come interagire con altre strutture come SharePoint 2010 e SQL Azure.”

La partecipazione è gratuita e dovete essere registrati sul sito, quindi se non lo avete ancora fatto… questa è l’occasione buona spacer
Nella pagina dell’evento troverete anche il link per accedere al meeting.

posted @ 6/16/2011 10:01 PM by Antonio Catucci

Unselect DataGridRow in DataGrid

Oggi si è presentato il seguente problema:
Ho usato una griglia per applicare una sorta di filtro su un altro controllo in base alle DataGridRow selezionate; il cliente ha voluto che, cliccando fuori dalle colonne di una DataGrid, tutte le righe selezionate si deselezionassero (eliminando in questo modo il filtro).

L’unico modo navito per farlo è cliccare sulla DataGridRow selezionata tenendo premuto il tasto CTRL.

Ho quindi creato il codice qui sotto.
In pratica cliccando al di fuori delle colonne (parte destra della Griglia) si clicca su un elemento figlio di una DataGridRow ma non su un elemento figlio di una DataGridCell (si può vedere facilmente con WPF Inspector oppure con Snoop).
Testo quindi questa condizione e deseleziono tutto se verificata:

public static class DataGridBehaviors
    {
        public static bool GetUnselectOnClickOutside(DependencyObject obj)
        {
            return (bool)obj.GetValue(UnselectOnClickOutsideProperty);
        }
        
        public static void SetUnselectOnClickOutside(DependencyObject obj, bool value)
        { 
            obj.SetValue(UnselectOnClickOutsideProperty, value); 
        }
        public static readonly DependencyProperty UnselectOnClickOutsideProperty = 
            DependencyProperty.RegisterAttached("UnselectOnClickOutside"typeof(bool), typeof(DataGridBehaviors), 
            new UIPropertyMetadata(false, UnselectOnClickOutsidePropertyChangedCallback));
        
        private static void UnselectOnClickOutsidePropertyChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs eventArgs)
        {
            DataGrid grid = depObj as DataGrid;
            if (depObj != null)
            {
                if ((bool)eventArgs.OldValue == false && (bool)eventArgs.NewValue == true)     
                    grid.MouseLeftButtonUp += AssociatedObjectUnselectOnClickOutside;
                else if 
                    ((bool)eventArgs.OldValue == true && (bool)eventArgs.NewValue == false)      
                    grid.MouseLeftButtonUp -= AssociatedObjectUnselectOnClickOutside;
            }
        }
        
        private static void AssociatedObjectUnselectOnClickOutside(object sender, MouseButtonEventArgs e) 
        {
            DataGrid datagrid = e.Source as DataGrid;
            DependencyObject originalControl = e.OriginalSource as DependencyObject; 
            DataGridCell cell; DataGridRow row;
            if (TryFindParent<DataGridRow>(originalControl, out row) && !TryFindParent<DataGridCell>(originalControl, out cell)) 
            { 
                datagrid.UnselectAll();
            }
        } 
        private static bool TryFindParent<T>(DependencyObject child, out T result) where T : class 
        {
            Contract.Requires(child != null"child could not be null"); 
            Contract.Ensures(Contract.Result<bool>() == true && Contract.ValueAtReturn<T>(out result) != null
                && result is T, "Result found rule violated"); 
            Contract.Ensures(Contract.Result<bool>() == false && Contract.ValueAtReturn<T>(out result) == null, 
                "Result not found rule violated"); 
            var parent = VisualTreeHelper.GetParent(child); 
            result = parent as T;
            if (result != null)  
                return true; 
            else        
                if (parent != null)
                    return TryFindParent<T>(parent, out result);
                else 
                    return false;
        }
    }

Questo è un behavior applicabile ad ogni griglia tramite AttachedProperty:

<DataGrid ItemsSource="{Binding}" local:DataGridBehaviors.UnselectOnClickOutside="True" />

Et voilà! Les jeux sont faits

posted @ 6/1/2011 3:47 PM by Roberto Sarati

WMAppManifest

Come probabilmente saprete, WMAppManifest.xml è un file presente nei progetti per windows phone 7, Silverlight o XNA che siano.

Questo file DEVE essere editato prima di pubblicare l’applicativo; una delle sezioni da editare è la parte delle “Capabilities”, ovvero quello che l’applicazione sfrutta del telefono (sensori, networking, telefono, location ecc…).
Quali elementi usa la nostra bellissima app? basta seguire questo:

frisoderidder.wordpress.com/2011/02/08/using-phone-7-capability-detection-tool/

In pratica tra i componenti installati dall’sdk c’è anche un tool che, dato in pasto un xml di regole e la cartella di output, mostra quali elementi impostare.

Quello che forse non tutti sanno è che c’è anche questa libreria gratuita coding4fun.codeplex.com/ con la quale è possibile leggere facilmente le informazioni presenti nel file in questione (creando così facilmente una pagina “About”).
Basta referenziare la dll e utilizzare la classe PhoneHelper per esempio, per recuperare la versione, nel seguente modo:

PhoneHelper.GetAppAttribute("Version");

posted @ 5/10/2011 10:08 PM by Roberto Sarati

HierarchicalDataTemplate

Dato che sul forum ci sono state molte domande riguardo il binding di wpf con i TreeView, ecco una semplice guida step-by-step.

Per prima cosa, se occorre eseguire un binding gerarchico, serve una sorgente dati gerarchica. Ora me ne vengono in mente due:

  1. Xml: per sua natura l’xml ha una struttura gerarchica e ben si adatta al treeview
  2. Oggetti (leggasi composite pattern): in pratica classi “Composite” che hanno una proprietà IEnumerable<Component> Children.

Per il poco che mi viene in mente, tutto può essere ricondotto al secondo caso (il primo incluso ma non ce ne è bisogno, si salti pure avanti).

OGGETTI + COSTRUZIONE GERARCHIA DA FLATHIERARCHY:

supponiamo di avere una lista di oggetti (che può essere benissimo una DataTable o qualsiasi altra cosa spacer ):
public class FlatHierarchyNode
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Text { get; set; }
}

Andremo a creare la nostra struttura nel seguente modo (ho lasciato da parte un po’ di “eleganza” e “pulizia” per comprimere il codice):

public class Composite
{
    public FlatHierarchyNode Node { get; set; }
    private List<FlatHierarchyNode> _allNodes;
 
    public Composite(FlatHierarchyNode node, List<FlatHierarchyNode> allNodes) 
    {
        this.Node = node;
        this._allNodes = allNodes;
    }
 
    private IEnumerable<Composite> _children;
    public IEnumerable<Composite> Children //nodi figlio del corrente nodo
    {
        get {
            if(_children == null)
                _children = Composite.getChildren(Node.Id, _allNodes);
            return _children;
        }
    }
    public static IEnumerable<Composite> getChildren(int? parentId, List<FlatHierarchyNode> allNodes)
    {
        return from node in allNodes //da tutti i nodi
                where node.ParentId == parentId //prendo i nodi figli
                select new Composite(node, allNodes); //ritornando un Composite
    }
}

è un po’ lunghetto ma abbastanza semplice. La parte principale è il metodo getChildren.
Avendo una struttura del genere, potremmo benissimo fare:
treeView1.ItemsSource = Composite.getChildren(null, new List<FlatHierarchyNode>(… … …));
Come eseguire il binding ora? Easy:

<TreeView Name="treeView1" >
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}">
            <TextBlock<">



gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.