0
votes

C # WPF Comment mettre à jour la collection observable après avoir mis à jour par programmation DataGrid - NO MVVM

J'ai un DataGrid lié à une collection observable. Ils ont un grand nombre de colonnes / propriétés que je dois opérer sur. Je dois faire une chaîne Remplacer sur une colonne choisie par l'utilisateur au moment de l'exécution via une combinaison. Entrez la description de l'image ici Donc, ce que je fais au début consiste à trouver l'index de la colonne (dans notre indice de description de cas = 2 à partir de 0), puis utilisez les substitutions avec le code ci-dessous. La variable III indique la ligne actuelle xxx

dans notre exemple, nous pouvons modifier la chaîne "pcacd" avec "AAA"

 Entrez la description de l'image ici

 Entrez la description de l'image ici

de sorte que" graphiquement "fonctionne, mais la collection observable n'est pas mise à jour avec la commande obccfgpartprograms = (Observablecollection ) dtgfeatures.itemsSource;

Je sais que je pouvais faire cela à travers chaque propriétés, mais qui serait ackward pour

- edit - Désolé des commentaires que je vois que je n'ai pas précisé. Mon mauvais.

J'ai donc un très grand nombre de propriétés (ici 9 mais potentiellement beaucoup plus), donc je n'écrirais pas quelque chose comme: xxx

...

puisque je peux éditer manuellement le DataGrid et refléter les modifications de la collection observable

DataGrid manuel Modifier ---> Modifications de la collection observable

Pourquoi ne pas avoir la possibilité d'avoir la possibilité d'être programmatique (par exemple avec la comparaison de chaîne) Modifier le DataGrid et reflétez les modifications apportées à l'OBC?

DataGrid Modification automatique ---> Modifications de la collection observable

Donc en bref: 1. Je suis capable de changer le DataGrid -> DTGFeatures [Property_x, Row_Y] = "AAAAAA"; 2. Je voudrais pouvoir modifier automatiquement OBC [Y] .x = "aaaaaa";

Il y en a un très grand nombre d'entre eux.

Merci pour toute aide Patrick


10 commentaires

Tout d'abord, MVVM ou pas? En outre, pourquoi changer l'élément d'interface utilisateur au lieu de changer l'observaBlection et déclencher un événement surpropertychanged?


Pas de mvvm désolé. Quant au reste s'il vous plaît voir mon édition


Si vous pouvez modifier programmablement le DataGrid, pourquoi ne pouvez-vous pas faire de même de la même chose avec l'observablecollection?


Parce que le datagrid est accessible avec index et cohordinates -> DataGrid.Cell [x, y]. Je ne connais pas une méthode pour faire la même chose avec une collection observable -> OBC [Membre X, ligne J]


Recherche d'un index dans une observablecollection , ce sont des index numériques cependant


Imaginez-moi, mais je ne comprends pas. Image que l'OBC est faite de classes AAA afin que l'observablecollection . Chaque instance AAA a diverses propriétés. Comme String ProP1 {get; set} prop2 {get; set} prop3 {get; set}. Par exemple, si je veux définir obc [3] .prop2, je ne veux pas faire OBC [3] .prop2 = "bonjour" mais OBC [3] [2] = "Bonjour". Je fais cela à travers un DataGrid mais qui ne fonctionne que visuellement sur le DataGrid et ne reflète pas l'observable


Peut-être par la réflexion?


Pourquoi voulez-vous faire obc [3] [2] = "bonjour"?


Afin de modifier ProP2 (numéro 2) de la troisième instance de l'OBC.


Cela peut également être réalisé en faisant obc [3] .prop2 = "bonjour"


3 Réponses :


0
votes

Vous devez modifier les données dans le Observablecollection à la place. Généralement, évitez toujours de manipuler les commandes d'interface utilisateur. Modifiez vos données et, si nécessaire, augmenter tinpropertychanged événement.


1 commentaires

Non, je ne peux pas voir mon édition.



1
votes

Si le textblock code> est lié à une propriété source de l'objet code> CFGPartPrograms code>, vous pouvez obtenir le nom de cette propriété à l'aide de la méthode getbindingexpression code> . Vous pouvez ensuite utiliser la réflexion pour définir la propriété sur une nouvelle valeur:

DataGridRow row = (DataGridRow)dtgFeatures.ItemContainerGenerator.ContainerFromIndex(iii);
if (row != null)
{
    var content = dtgFeatures.Columns[indexColumnToOperateOn].GetCellContent(row);
    if (content != null)
    {
        TextBlock textBlock = (TextBlock)content;
        if (textBlock.Text.ToUpper().Trim().Contains(tbxSrc.Text.ToUpper().Trim()))
        {
            string str = textBlock.Text.Replace(tbxSrc.Text, tbxDest.Text);
            textBlock.Text = str;
            BindingExpression be = textBlock.GetBindingExpression(TextBlock.TextProperty);
            if (be != null && be.ParentBinding != null && be.ParentBinding.Path != null && !string.IsNullOrEmpty(be.ParentBinding.Path.Path))
            {
                object cfgPartPrograms = textBlock.DataContext;
                if (cfgPartPrograms != null)
                {
                    System.Reflection.PropertyInfo pi = typeof(CfgPartPrograms).GetProperty(be.ParentBinding.Path.Path);
                    if (pi != null)
                        pi.SetValue(cfgPartPrograms, str);
                }
            }
        }
    }
}


1 commentaires

Cela semble très prometteur! Sauf que cela ne fonctionne pas. J'ai fabriqué des modifications pour le renvoyer non seulement à la rangée 0 et au col 0 (les modifications doivent être examinées par les pairs). Mais à part cela, même si le DataGrid est mis à jour, une liaison à la liaison est toujours nulle et donc l'inter si (soyez! Null) n'est jamais entérin ;-(



3
votes

Oui, cela peut être fait. Le chemin de passage est le suivant:

Imaginez avoir la classe suivante: p> xxx pré>

Nous pouvons donc créer et remplir l'OBC: P>

public static class ObservableCollectionExtensions
{
public static ObservableCollection<T> SetValue<T>(this ObservableCollection<T> obc, int rowNumFromZero, int propNumFromZero, string str)
{
    int rowCounter = -1;
    foreach (var itemObc in obc)
    {
        rowCounter++;
        PropertyInfo[] Fields = itemObc.GetType().GetProperties();
        int propCounter = -1;
        foreach (PropertyInfo field in Fields)
        {
            propCounter++;
            if (rowCounter == rowNumFromZero)
            {
                var currentField = field.GetValue(itemObc, null);
                if (currentField != null)
                {
                    var t = currentField.GetType();
                    if (t == typeof(string) && propCounter == propNumFromZero)
                        field.SetValue(itemObc, str);
                }
            }
        }
    }
    return obc;
}


0 commentaires