Overblog Suivre ce blog
Administration Créer mon blog

Présentation

  • : Romagny13 - Du .NET,du pur .NET
  • Romagny13 - Du .NET,du pur .NET
  • : Cycle de progression Faire (quelque chose qui marche) -> comprendre ce que l’on fait/comment cela marche -> pousser plus loin les notions
  • Contact

Recherche

Articles Récents

4 avril 2014 5 04 /04 /avril /2014 22:08

Bien coder ne suffit plus. Il faut être en mesure de proposer une bonne expérience utilisateur. Blend est l’outil qui permet de définir ses IHM en Xaml.Cet article a pour but de découvrir la bête qui n’est pas forcément  simple d’accès .

 

1- Projets

 

On distingue principalement 3 types de projets (WPF,Silverlight et SketchFlow)

 

 

2- Générer /Exécuter le projet (menu « Projet »)  

F12 Générer le projet (affichage de la fenêtre « Résultats »)
F5 Exécuter le projet

3- Switcher rapidement d’espace de conception

Modes(Menu « Affichage ») :Création,Code et Mixte 
Switch via bouton Ou F11  
Définir la fenêtre de démarrage(StarupUri est modifié dans App.xaml)

 

4-Espaces de travail

2 espaces de travail(menu « Fenêtre ») : Design et Animation
CTRL + F11 poiur un switch rapide
Note : ill est possible d’enregistrer son propre espace de travail

5 – Raccourcis

Outils de sélection
Loupe
Pipette : copie la couleur/dégradé
Pot de peinture : remplit une zone fermée avec la couleur/dégradé
Plume
Forme : rectangle,ellypse,ligne
Conteneurs : Grid,Canvas,etc.
Contrôles de texte : TextBlock,Textbox,etc.
Contrôles : button,checkbox,tabControl,etc.

 

A cela s’ajoute la boîte contenant tous les contrôles,formes,etc. disponibles .

6-Propriétés 

Pinceau et apparence:
 

Fill : remplissage
Stroke : le contour pour une forme
Foreground : couleur de la police
Etc.
 
Dégradé linéaire (droite à gauche),radial 

Pinceau,couleur unie,dégradé,mosaïque(image),ressources
Boutons permettant de régler les couleurs sur la barre
GradientOrigin permet de  personnaliser le début dégradé
Opacity : transparence
Etc.

Propriétés communes :
Strecth : Fill,Uniform(par défaut),…

7-Grouper un élément

 

8-Evènements avec Blend

Repost 0
Published by Romagny13 - dans Blend
commenter cet article
2 avril 2014 3 02 /04 /avril /2014 17:50

 

 
MainWindow

 

   <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.50*" />
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
 
            <Button Command="{Binding DisplayArticleListViewCommand}" Content="Liste d'articles" Grid.Row="0" Margin="5 5 5 5" />
            <Button Command="{Binding DisplayArticleViewCommand}" Content="Détails"  Grid.Row="1" Margin="5 5 5 5"/>
        </Grid>
 
           <ContentPresenter Content="{Binding CurrentViewModel}"  Grid.Column="1"/>
    </Grid>

 
MainWiewModel

  public class MainViewModel : ViewModelBase
    {
        // ViewModels affichables
        public ArticleListViewModel ArticleListViewModel { get; set; }
        public ArticleViewModel ArticleViewModel { get; set; }
        private ViewModelBase _currentViewModel;
        // ViewModel courant
        public ViewModelBase CurrentViewModel
        {
            get { return _currentViewModel; }
            set
            {
                _currentViewModel = value;
                RaisePropertyChanged<ViewModelBase>(() => CurrentViewModel);
            }
        }
        // Commandes
        public RelayCommand<MainViewModel> DisplayArticleListViewCommand { get; set; }
        public RelayCommand<MainViewModel> DisplayArticleViewCommand { get; set; }
 
        public MainViewModel() { }
        protected override void InitializeCommands()
        {
            DisplayArticleListViewCommand = new RelayCommand<MainViewModel>(_ => DisplayArticleListView(), this);
            DisplayArticleViewCommand = new RelayCommand<MainViewModel>(_ => DisplayArticleView(), this);
        }
 
        private void DisplayArticleListView()
        {
            if (ArticleListViewModel == null)
                ArticleListViewModel = new ArticleListViewModel();
 
            CurrentViewModel = ArticleListViewModel;
        }
 
        private void DisplayArticleView()
        {
            if (ArticleViewModel == null)
                ArticleViewModel = new ArticleViewModel();
 
            CurrentViewModel = ArticleViewModel;
        }    
    }

 

En ressource (permet de définir la View associée à un ViewModel) 
        <DataTemplate DataType="{x:Type ViewModel:ArticleListViewModel}">
            <View:ArticleListView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type ViewModel:ArticleViewModel}">
            <View:ArticleView />
        </DataTemplate>

 

Le code des ViewModels et Views est classique et présente peu d’intérêt .
A savoir que l’on définit le DataContext de MainWidow sur nouveau MainViewModel
Plus loin
Il est possible aussi de définir une ObservableCollection<ViewModelBase> ou créer une classe spécifique qui hérite de ViewModelBase et utiliser un control comme le TabControl
Repost 0
Published by Romagny13 - dans MVVM
commenter cet article
2 avril 2014 3 02 /04 /avril /2014 00:31

1-Définition des « VisualState »
Le squelette se présente ainsi

   <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="Normal" />
                     
                <VisualState x:Name="Loading">
                    <Storyboard>
                        <!-- Animations -->
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

 

2-Trigger ou Code-behind

Ajouter un référence à System.Windows.Interactivity et Microsoft.Expression.Interactions
Puis les namespaces :
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei=http://schemas.microsoft.com/expression/2010/interactions
Exemple :
Je suis bindé à CurrentState , une simple propriété de mon ViewModel .Il y a un état pour la valeur « Normal » du CurrentState et un état « Loading » (correspondant  au chargement) .
  public class ArticleMasterDetailsViewModel :ListViewModelBase<ArticleViewModel>
  {
        private string _currentState;

 

        public string CurrentState
        {
            get { return _currentState; }
            set
            {
                _currentState = value;
                RaisePropertyChanged<string>(() => CurrentState);
            }
        }
    // etc.
}

 

On peut changer la valeur de ce CurrentState à chaque chargement .Intéressant si on charge des données de manière asynchrone.

 

L’EventTrigger ayant EventName= »Loaded » s’exécute automatiquement au chargement du usercontrol/Window
<i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding CurrentState}" Value="Normal">
                <ei:GoToStateAction StateName="Normal"/>
            </ei:DataTrigger>
            <ei:DataTrigger Binding="{Binding CurrentState}" Value="Loading">
                <ei:GoToStateAction StateName="Loading"/>
            </ei:DataTrigger>
            <i:EventTrigger EventName="Loaded">
                <ei:GoToStateAction StateName="Loading"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>



Il est possible aussi de Changer l’état visuel depuis le code – behind
Si c’est un UserControl on utilisera GoToState
VisualStateManager.GoToState(control1, "Loading", true)
Sinon (LayoutRoot correspondant au nom de mon Grid principal)
VisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, "Loading", true);

 

3-Un exemple
Un exemple qui se contente de cacher une grille pour afficher une autre avec un message « Chargement » .
Blend est tout indiqué pour définir des animations.

 

  <Grid x:Name="LayoutRoot" >
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="Normal" />
                                         
                <VisualState x:Name="Loading">
                    <Storyboard>
                        <!-- Cache mainGrid -->
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="mainGrid">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Collapsed</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <!-- Affiche loadingGrid -->
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="loadingGrid">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
 
        <Grid x:Name="loadingGrid" Opacity="1"  Visibility="Collapsed"  Background="Black">
            <Label Content="Chargement ..." FontSize="25" Foreground="White" VerticalAlignment="Bottom" HorizontalAlignment="Center" />
        </Grid>
       
        <Grid x:Name="mainGrid">
<!-- contrôles de la page(textbox,boutons,etc.) -->
        </Grid>
     
    </Grid>

 

Après libre d’utiliser Trigger + binding sur propriété ou VisualStateManager dans le code-behind,ajouter des animations/Transformations
async1.png
Repost 0
Published by Romagny13 - dans Xaml
commenter cet article
1 avril 2014 2 01 /04 /avril /2014 16:04
Repost 0
Published by Romagny13 - dans ASP.NET
commenter cet article
30 mars 2014 7 30 /03 /mars /2014 18:40

II ADO.NET Entity Framework

 

1-Utilisation directe des POCO générées avec EDM
Exemple on a une ObservableCollection<Article> .Article étant généré avec le designer EDM.
Peu de changements par rapport à LINQ To SQL .Les changements se font de manière transparente. Seuls l’ajout et la modification demandent un peu de code.
private void Articles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                Article newArticle = e.NewItems[0] as Article;
                newArticle.ArticleID = Guid.NewGuid();
 
                if (!context.Articles.Local.Contains(newArticle))
                    context.Articles.Add(newArticle);
            }
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                Article oldArticle = e.OldItems[0] as Article;
 
                if (context.Articles.Local.Contains(oldArticle))
                    context.Articles.Remove(oldArticle);
            }
                     
        }
 
        private void CurrentArticle_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
 
        }

 

2- N-Tiers

alldata2.png
 
ViewModel
   private void Articles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                ArticleModel newArticle = e.NewItems[0] as ArticleModel;
                newArticle.ArticleID = Guid.NewGuid();
                articleService.Add(newArticle);
            }
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                ArticleModel oldArticle = e.OldItems[0] as ArticleModel;
                articleService.Remove(oldArticle);
            }
        }
        private void CurrentArticle_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            articleService.Update(CurrentArticle);
        }

 

Service
  public class ArticleService :IArticleService
    {
        private DbTradingEntities context = new DbTradingEntities();
 
        private List<ArticleModel> MapToModel(List<Article> articles)
        {
            List<ArticleModel> result = new List<ArticleModel>();
            foreach (Article article in articles)
            {
                result.Add(article.ToModel());
            }
            return result;
        }
 
        public List<ArticleModel> GetAll()
        {
            return MapToModel(context.Articles.ToList());
        }
 
        public void Add(ArticleModel model)
        {
            context.Articles.Add(model.ToEntity());
                     
        }
 
        public void Update(ArticleModel model)
        {
            if (context.Articles.Where(a => a.ArticleID == model.ArticleID).Count() > 0)
            {
                Article oldArticle = context.Articles.Single(a => a.ArticleID == model.ArticleID);
                context.Entry(oldArticle).CurrentValues.SetValues(model.ToEntity());
            }
                    
            if (context.Articles.Local.Where(a => a.ArticleID == model.ArticleID).Count() > 0)
            {
                Article oldArticle = context.Articles.Local.Single(a => a.ArticleID == model.ArticleID);
                context.Entry(oldArticle).CurrentValues.SetValues(model.ToEntity());
            }                      
                    
        }
 
        public void Remove(ArticleModel model)
        {
 
            if (context.Articles.Where(a => a.ArticleID == model.ArticleID).Count() > 0)
            {
                Article oldArticle = context.Articles.Single(a => a.ArticleID == model.ArticleID);
                context.Articles.Remove(oldArticle);
            }
            // Local (un élément qui vient d'être ajouté)
            if (context.Articles.Local.Where(a => a.ArticleID == model.ArticleID).Count() > 0)
            {
                Article oldArticle = context.Articles.Local.Single(a => a.ArticleID == model.ArticleID);
                context.Articles.Local.Remove(oldArticle);
            }
                     
        }
 
        public int SaveAll()
        {
           return context.SaveChanges();
        }
 
    }

 

Mapper identique à celui pour LINQ To SQL
public static ArticleModel ToModel(this Article entity)
             {
                    ArticleModel model = new ArticleModel()
                    {
                           ArticleID = entity.ArticleID,
                           ArticleName = entity.ArticleName,
                           Description = entity.Description,
                           UnitPrice = entity.UnitPrice,
                                       Collection = new CollectionModel() { CollectionID = entity.Collection.CollectionID,  CollectionName = entity.Collection.CollectionName }          
            };
                    return model;
       }
 
        // MODEL > DB
             public static Article ToEntity(this ArticleModel model)
             {
                    Article entity = new Article()
                    {
                           ArticleID = model.ArticleID,
                           ArticleName = model.ArticleName,
                           Description = model.Description,
                           UnitPrice = model.UnitPrice,
                           CollectionID = model.Collection.CollectionID,
                          
                    };
                    return entity;
             }
       }
 

 

Enfin,Il est possible de vérifier l’EntityState des lignes à insérer,modifier,supprimer en passant .Je donne des informations pour cela dans un précédent post
Repost 0
Published by Romagny13 - dans Entity Framework
commenter cet article
30 mars 2014 7 30 /03 /mars /2014 18:38

2 « méthodes »

Par binding : les opérations d’ajout, modification, suppression se font de manière relativement « transparente » grâce au binding ,le but étant de connecter les opérations d'ajout/suppression/modification entre la couche métier et la couche d'accès aux données .ce jusqu’à ce que l’utilisateur valide les changements (en appuyant sur un bouton appelant SubmitChanges()) avec les risques que cela peut comporter de « dérapages » si tout n’est pas maitrisé .
Par code en contrôlant d’avantage chaque action .Avec par exemple l’ouverture d’une fenêtre édition pour l’ajout et la modification .Même si une fois le binding maitrisé cela revient au même.
I LINQ TO SQL
1-Binding direct
Exemple avec une ObservableCollection<Article>, Article étant l’entité métier générée avec LINQ To SQL
On repère les opérations d’ajout et suppression grâce à l’évènement CollectionChanged
  private void Articles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                Article newArticle = e.NewItems[0] as Article;
                newArticle.ArticleID = Guid.NewGuid();
 
                if (!context.Article.Contains(newArticle))
                    context.Article.InsertOnSubmit(newArticle);
            }
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                Article oldArticle = e.OldItems[0] as Article;
 
                if (context.Article.Contains(oldArticle))
                    context.Article.DeleteOnSubmit(oldArticle);
                if (context.GetChangeSet().Inserts.Contains(oldArticle))
                    context.Article.DeleteOnSubmit(oldArticle);
            }
        }
private void CurrentArticle_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { }

 

La modification se fait de manière totalement transparente. Mais si on voulait pouvoir la contrôler il faudrait s’abonner l’évènement PropertyChanged de l’élément courant

 

2-ChangeSet :
Vous pouvez vérifier les éléments « Inserts,Updates,Deletes » qui seront mis à jour au prochain « SubmitChanges » .A savoir que les éléments sont en lecture seule .
private TradingDataContext context = new TradingDataContext();
ChangeSet changeSet = context.GetChangeSet();

 

changeSet.Inserts
changeSet.Updates
changeSet.Deletes

 

3- N-Tiers – Mapping
aalldata1.png
 
On peut préférer avoir une application bien découplée et ne pas travailler directement avec les entités générées par LINQ To SQL ou EDM. Le but ici sera d'arriver à synchroniser correctement les actions ajout/Suppression/Modification entre les différentes couches .
Par exemple avec MVVVM ,J’ai :
ArticleModel
Article
et ArticleMapper permettant de faire le mapping entre le modèle et l’entité métier
Dans mon ViewModel
J’ai une ObservabelCollection<ArticleModel> et un CurrentArticle pour lequel je m’abonne à l’évènement PropertyChanged .
private void Articles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                ArticleModel newArticle = e.NewItems[0] as ArticleModel;
                articleService.Add(newArticle);
            }
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                  ArticleModel oldArticle = e.OldItems[0] as ArticleModel;
                  articleService.Remove(oldArticle);
            }
        }
 
private void CurrentArticle_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
 
                articleService.Update(CurrentArticle);
        }

 

Dans ArticleService
  public class ArticleService :IArticleService
    {
        private TradingDataContext context = new TradingDataContext();
 
 
        private List<ArticleModel> MapToModel(List<Article> articles)
        {
            List<ArticleModel> result = new List<ArticleModel>();
            foreach (Article article in articles)
            {
                result.Add(article.ToModel());
            }
 
            return result;
        }
 
        public List<ArticleModel> GetAll()
        {
            return MapToModel(context.Article.ToList());
        }
 
        public void Add(ArticleModel model)
        {
            context.Article.InsertOnSubmit(model.ToEntity());
 
        }
 
        public void Update(ArticleModel model)
        {
            if (context.Article.Where(a => a.ArticleID == model.ArticleID).Count() > 0)
            {
                Article oldArticle = context.Article.Single(a => a.ArticleID == model.ArticleID);
                context.Article.Attach(model.ToEntity(), oldArticle);
            }
 
            if (context.GetChangeSet().Inserts.Count(c => ((Article)c).ArticleID == model.ArticleID) > 0)
            {
                Article oldArticle = (Article)context.GetChangeSet().Inserts.Single(a => ((Article)a).ArticleID == model.ArticleID);
                context.Article.DeleteOnSubmit(oldArticle);
                context.Article.InsertOnSubmit(model.ToEntity());
            }
 
        }
 
        public void Remove(ArticleModel model)
        {
            Article oldArticle =  context.Article.Single(a => a.ArticleID == model.ArticleID);
 
            if (context.Article.Contains(oldArticle))
                context.Article.DeleteOnSubmit(oldArticle);
            if (context.GetChangeSet().Inserts.Contains(oldArticle))
               context.Article.DeleteOnSubmit(oldArticle);
        }
 
        public void SaveAll()
        {
            context.SubmitChanges();
        }
    }



Le Mapper – « Collection » correspond à une colonne de clé étrangère(CollectionID) .Attention à ne pas créer de nouvelle instance dans le sens model > Linq car sinon cela serait vu comme un élément à insérer(en gros une nouvelle collection à insérer dans la base de données)

public static class ArticleMapper
       {
        // DB > MODEL
             public static ArticleModel ToModel(this Article entity)
             {
                    ArticleModel model = new ArticleModel()
                    {
                           ArticleID = entity.ArticleID,
                           ArticleName = entity.ArticleName,
                           Description = entity.Description,
                           UnitPrice = entity.UnitPrice,
                           Collection = new CollectionModel() { CollectionID = entity.Collection.CollectionID,  CollectionName = entity.Collection.CollectionName }         
            };
                    return model;
       }
 
        // MODEL > DB
             public static Article ToEntity(this ArticleModel model)
             {
                    Article entity = new Article()
                    {
                           ArticleID = model.ArticleID,
                           ArticleName = model.ArticleName,
                           Description = model.Description,
                           UnitPrice = model.UnitPrice,
                           CollectionID = model.Collection.CollectionID,
                          
                    };
                    return entity;
             }
       }
 
Repost 0
Published by Romagny13 - dans Linq To SQL
commenter cet article
29 mars 2014 6 29 /03 /mars /2014 17:53

J’utilise la réflexion.

L’avantage est de ne pas avoir à implémenter IEditableObject dans chaque POCO  .Il y a peut-être moyen de faire mieux mais l’idée est là.
Exemple avec ModelBase avec MVVM .
    public class ModelBase :
        ObservedBase,
        IDataErrorInfo,
        IEditableObject
    {
 
       // code retiré pour la clarté
 
       #region IEditableObject
 
        private Dictionary<string, object> _cache;
 
        public void BeginEdit()
        {
            _cache = new Dictionary<string, object>();
 
            IEnumerable<PropertyInfo> properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite);
            foreach (PropertyInfo property in properties)                    
                _cache.Add(property.Name, property.GetValue(this, null));
                                 
 
        }
 
        public void CancelEdit()
        {
            if (_cache != null)
            {
                IEnumerable<PropertyInfo> properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite);
 
                foreach (PropertyInfo property in properties)
                    property.SetValue(this, _cache[property.Name], null);
 
                _cache = null;
            }
        }
 
        public void EndEdit()
        {
            _cache = null;                    
        }
 
        #endregion
    } 

 

 
Repost 0
Published by Romagny13 - dans MVVM
commenter cet article
29 mars 2014 6 29 /03 /mars /2014 13:21

ListCollectionView est la vue par défaut sur une collection implémentant IList .
 
Une vue permet de filtrer, trier et naviguer facilement(ancien article en parlant) mais permet aussi de gérer les opérations d’ajout d’un nouvel élément, modification et suppression.

1-Ajout :
L’intérêt est de pouvoir annuler un ajout à la collection facilement.
  • AddNew()  ajoute l’élément à la collection et à la vue(mais est également le CurrentItem et CurrentAddItem de la vue,IsAddinNew = true)
  • CancelNew() supprime l’élément en cours d’ajout de la collection et la vue(CurrentItem ,CurrentAddItem,IsAddindNew=false)
  • CommitNew() CurrentAddItem ne pointe plus sur l’objet,IsAddind= false , l’objet appartient à la collection et à la vue comme un autre élément .

 

Exemple (Articles est une ObservableCollection<Article>)
public ListCollectionView View { get; set; }

 

View = (ListCollectionView)(CollectionViewSource.GetDefaultView(context.Articles));

 

Article newArticle = (Article)View.AddNew();
newArticle.ArticleID = Guid.NewGuid();
newArticle.ArticleName = "Jeans bleu délavé";
newArticle.Description = "joli jeans bleu clair délavé";
newArticle.CollectionID = 1;

 

// Sur un bouton « Ok » par exemple
View.CommitNew();

       
 

// Sur un bouton « Annuler »
View.CancelNew();



Note : AddNewItem(object item) fonctionne de la même manière que AddNew()
  
2-Modification :
Tout l’intérêt ici est de pouvoir annuler les changements apportés à un objet de la collection (la classe doit avoir implémenté IEditableObject)
  • EditItem(object item) spécifie l’objet qui va être édité(CurrentEditItem,IsEditingItem=true)
  • CancelEdit() permet d’annuler les changements sur l’objet(l’objet n’est plus CurrentEditItem et isEditingItem=false)
  • CommitEdit() valide les changements(l’objet n’est plus CurrentEditItem et isEditingItem=false)    

 

Exemple :
Article article =(Article) View.CurrentItem;
View.EditItem(article);

 

article.ArticleName = "Jeans xxy";

 

//    
View.CancelEdit();

 

//      
View.CommitEdit();

 

3-Suppression :
On peut aussi passer par la vue avec les méthodes Remove(object item) ou RemoveAt(int index) pour supprimer un objet de la collection
Exemple
   Article article =(Article) View.CurrentItem;
 
   View.Remove(article);



Repost 0
Published by Romagny13 - dans C
commenter cet article
28 mars 2014 5 28 /03 /mars /2014 01:34

TargetNullValue est pratique par exemple pour les formulaires afin d’éviter les champs vides.

 

A - On peut soit définir directement
<TextBox Text="{Binding CurrentArticle.Description,TargetNullValue='Entrez la description'}" />
B - Ou dans un dictionnaire de ressources (ou dans les ressources de la page/conteneur)
    <sys:String x:Key="targetNullName">Entrez le nom de l'article</sys:String>         
On ajoute le namespace xmlns:sys="clr-namespace:System;assembly=mscorlib"
On peut ainsi accéder facilement à la ressource depuis l’application et contourner le problème des apostrophes
(code simplifié pour la clarté de l’exemple)
<TextBox Text="{Binding CurrentArticle.ArticleName,TargetNullValue={StaticResource targetNullName} }"/>    
Repost 0
Published by Romagny13 - dans Xaml
commenter cet article
27 mars 2014 4 27 /03 /mars /2014 20:13

Exemple : la ComboBox affiche une liste de catégories, la catégorie sélectionnée correspond à celle de l’article

 

1-Une ComboBox « classique »
que l’on pourrait retouver dans une vue détails .
  • ItemsSource : ce  doit être un énumérable (exemple une observableCollection AllCategories)
  • DisplayMemberPath : la valeur affichée(exemple : CategoryName de AllCategories)
  • SelectedValuePath : la valeur « cachée » dans la source (exemple CategoryID de AllCategories)
  • SelectedValue : la valeur à sélectionner de l’objet (exemple CategoryID de CurrentArticle)
  • SelectedItem : l’objet qui sera mis à jour en cas de modification à partir de l’UI ou par code) (important, exemple si la source est une ObservableCollection<Category> ,alors il faut donner un SelectedItem de type « Category »)
      <ComboBox    ItemsSource="{Binding AllCategories}"
                   SelectedValuePath="CategoryID"
                   DisplayMemberPath="CategoryName"
                   SelectedValue="{Binding CurrentArticle.Category.CategoryID}"
                   SelectedItem="{Binding CurrentArticle.Category}"
                   />

 

2-Une ComboBox dans un Datagrid définie avec un Template
(ici Avec DataGridTemplateColumn)  
   <DataGrid      ItemsSource="{Binding Articles}"
                  SelectedItem="{Binding CurrentArticle,Converter={StaticResource ignoreNewItemPlaceHolderConverter}}"
                  AutoGenerateColumns="False">
 
            <DataGrid.Resources>
                <DataTemplate x:Key="combo" >
                    <Border>
                        <ComboBox       ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.AllCategories}"
                                        SelectedValuePath="CategoryID"
                                        DisplayMemberPath="CategoryName"
                                        SelectedValue="{Binding Category.CategoryID}"
                                        SelectedItem="{Binding Category,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                        SelectionChanged="ComboBox_SelectionChanged"
                                        />
                    </Border>
                </DataTemplate>
            </DataGrid.Resources>
 
            <DataGrid.Columns>
                <!— colonnes classiques -->
                <DataGridTextColumn Header="Nom"  Binding="{Binding ArticleName,UpdateSourceTrigger=PropertyChanged}" Width="SizeToCells" />
                <DataGridTextColumn Header="Description"  Binding="{Binding Description,UpdateSourceTrigger=PropertyChanged}" Width="SizeToCells"/>
                <DataGridTextColumn Header="Prix"  Binding="{Binding UnitPrice, StringFormat=\{0:C\},UpdateSourceTrigger=PropertyChanged}" Width="SizeToCells"/>
                <!— Utilisation DataGridTemplateColumn -->
                <DataGridTemplateColumn CellTemplate="{StaticResource combo}" />
            </DataGrid.Columns>
        </DataGrid>

 

    Il est également possible de récupérer dans le code-behind l’élément sélectionné(SelectedItem)  
        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Définir la catégorie de l'élément par code au changement dans le datagrid
            Category category = ((ComboBox)sender).SelectedItem as Category;                         
                  context.CurrentArticle.Category = category;
 
        }

 

3-DataGridComboBoxColum
On définit la source de données pour l’état « en édition » et l’état normal
Important car sinon tout simplement vous vous retrouverez avec une liste vide.
<DataGrid         ItemsSource="{Binding Articles}"
                  SelectedItem="{Binding CurrentArticle}"
                  AutoGenerateColumns="False">
 
                <DataGridComboBoxColumn Header="Catégorie"
                                        SelectedValuePath="CategoryID"
                                        DisplayMemberPath="CategoryName"
                                        SelectedValueBinding="{Binding Category.CategoryID}"
                                        SelectedItemBinding="{Binding Category,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                        Width="SizeToCells">
 
                    <DataGridComboBoxColumn.ElementStyle>
                        <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.AllCategories}" />
                        </Style>
                    </DataGridComboBoxColumn.ElementStyle>
 
                    <DataGridComboBoxColumn.EditingElementStyle>
                        <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.AllCategories}" />
                        </Style>
                    </DataGridComboBoxColumn.EditingElementStyle>
                </DataGridComboBoxColumn>
            </DataGrid.Columns>
        </DataGrid>

 

 
Repost 0
Published by Romagny13 - dans Xaml
commenter cet article