2010-12-06 31 views
4

J'ai une page avec deux contrôles, une grille de données et un formulaire de données.Silverlight dataform currentitem issue

Dans la grille de données, j'ai une liste de tous les objets d'une certaine classe. Lorsqu'un utilisateur sélectionne un élément dans la grille de données, le formulaire est chargé avec l'objet sélectionné.

dataForm.CurrentItem = view.CurrentItem; view est un PagedCollectionView qui contient uniquement l'élément sélectionné.

Mon problème est, lors de la définition de la propriété currenitem du formulaire de données, si j'utilise uniquement PagedCollectionView (vue) sans .CurrentItem, je perds la validation sur le formulaire de données. Tous les champs requis ne sont pas considérés comme requis. Si j'utilise pcv.CurrentItem alors que la validation CurrentItem de mon formulaire fonctionne correctement, un autre problème se pose.

Lors de l'utilisation de l'élément en cours PagedCollectionView comme élément actif du groupe de données:

Un utilisateur sélectionne un élément dans la grille et l'objet est chargé bien dans le groupe de données. Si un utilisateur modifie une certaine valeur dans l'un des champs de texte du formulaire, puis sélectionne un autre élément pour charger le formulaire, l'erreur suivante est générée:

"Impossible de changer la devise lorsqu'un élément comporte des erreurs de validation ou qu'il est En cours de modification et AutoCommit est faux. Définissez ItemsSource à ICollectionView pour gérer la devise à la place. " Je n'utilise pas les propriétés de pagination du formulaire de données et j'ai mon propre bouton de sauvegarde sur le formulaire.

J'apprécierais toute aide, ceci est mon premier projet de silverlight sur lequel je travaille. Edit-J'ai utilisé dataform.CommitEdit lors de la modification de l'adresse courante du dataform. Une chose que cela n'a pas résolu est s'il y a une erreur de validation sur le formulaire, l'erreur de devise est levée. Y at-il de toute façon à contourner cela. AutoEdit est vrai et AutoCommit est faux pour le formulaire

Répondre

4

Il est un peu difficile de déterminer exactement ce qui se passe ici sans un échantillon, mais voici une observation qui peut aider à résoudre le problème. Essayez plutôt de lier la propriété ItemsSource de DataGrid et DataForm à la vue de collection, et ne pas lier la propriété CurrentItem du DataForm. Ils sont magiquement conservés en synchronisation (l'élément sélectionné dans le DataGrid définira l'élément actuel dans le DataForm) - c'est une fonctionnalité de la CollectionView. Cela peut ou non résoudre votre problème, mais de toute façon cela ne fera pas de mal :).

Auto-promotion flagrante: ceci et d'autres caractéristiques de la CollectionView sont couvertes dans mon livre Pro Business Applications with Silverlight 4 :).

+0

Salut Chris, merci pour la suggestion. J'ai essayé cette méthode et j'ai toujours la même erreur. – user531958

+1

J'ai essayé ce que Jhelumi a fait dans son poste (semble que nous avions le même problème) http://stackoverflow.com/questions/3969588/silverlight-4-and-dataform-and-currenitem-and-autocommit – user531958

+0

Et cela semble avoir résolu le problème. Merci beaucoup si – user531958

1

J'ai eu ce problème beaucoup de fois. Et toujours au cas où ajouter un nouvel article. Après quelques jours frustrants, j'ai téléchargé les codes sources de Silverlight toolkit. (Vous pouvez trouver dans le répertoire Programmes FIles (Mine était C: \ Program Files (x86) \ Microsoft SDK \ Silverlight \ v4.0 \ Toolkit \ Apr10 \ Source)) Compile et référence au lieu de l'assembly System.Windows. Controls.Data.DataForm.Toolkit

en mode débogage, nous voyons un comportement étrange dans DataForm.cs:

private static void OnCurrentItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      DataForm dataForm = d as DataForm; 
      if (dataForm != null && !dataForm.AreHandlersSuspended()) 
      { 
       if (dataForm._lastItem != null && dataForm.ShouldValidateOnCurrencyChange) 
       { 
        dataForm.ValidateItem(); 
       } 

       if ((!dataForm.AutoCommitPreventsCurrentItemChange && dataForm.IsItemValid) && 
        (e.NewValue == null || 
        dataForm._collectionView == null || 
        dataForm._collectionView.Contains(dataForm.CurrentItem) 
        )) 
       { 
        dataForm.SetUpNewCurrentItem(); 
        dataForm.GenerateUI(true /* clearEntityErrors */, true /* swapOldAndNew */); 
        dataForm.UpdateCurrentItem(); 
        SetAllCanPropertiesAndUpdate(dataForm, false /* onlyUpdateStates */); 
        dataForm._lastItem = dataForm.CurrentItem; 
        dataForm.OnCurrentItemChanged(EventArgs.Empty); 
       } 
       else 
       { 
        dataForm.SetValueNoCallback(e.Property, e.OldValue); 
        throw new InvalidOperationException(string.Format(Globalization.CultureInfo.InvariantCulture, System.Windows.Controls.Data.DataForm.Toolkit.Resources.DataForm_CannotChangeCurrency, "AutoCommit", "ItemsSource", "ICollectionView")); 
       } 
      } 
     } 

dataForm._collectionView.Contains (DataForm.CurrentItem) retourne false même le même objet existe dans dataForm._collectionView

J'ai changé sous condition:

if ((!dataForm.AutoCommitPreventsCurrentItemChange && dataForm.IsItemValid) && 
        (e.NewValue == null || 
        dataForm._collectionView == null || 
        dataForm._collectionView.Contains(dataForm.CurrentItem) || 
        dataForm.CurrentItem == e.NewValue 
        )) 

Et DataForm a commencé à travailler très bien. Sans exception et erreurs.

0
private void DataForm_EditEnding(object sender, DataFormEditEndingEventArgs e) 
{ 
    if (e.EditAction == DataFormEditAction.Commit) 
    { 
     ... 
    } 
    else 
    { 
     DataForm1.ValidationSummary.Errors.Clear(); 
    } 
} 
0

Vérifier toute erreur de validation lorsque vous liez l'élément en cours, si vous avez les effacer alors BindingItem.ValidationErrors.Clear(); puis liez l'élément à la forme de données.