2017-09-21 7 views
0

Je suis novice dans WPF et j'essaie d'apprendre les bases de la construction d'un outil simple pour gagner du temps. Ici, j'essaie de lire un fichier distant pour obtenir le statut et mettre à jour la grille de données avec le nom de la machine et l'état du fichier.WPF - Mise à jour des valeurs ROW existantes au lieu d'une nouvelle ligne dans DataGrid à l'aide de ObserableCollections

est sous le code CS:

public partial class MainWindow : Window 
{ 
    private ObservableCollection<User> users = new ObservableCollection<User>(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     lbUsers.ItemsSource = users; 
    } 

    private void btnCheckStatus_Click(object sender, RoutedEventArgs e) 
    { 
     var fileStream_status = new FileStream(@"\\LBSTR\c$\temp\range.dat", FileMode.Open, FileAccess.Read); 
     using (var streamReader = new StreamReader(fileStream_status, Encoding.UTF8)) 
     { 
      string line; 
      while ((line = streamReader.ReadLine()) != null) 
      { 
       if (line.Equals("A")) 
       { 
        users.Add(new User() { MachineName = "LBSTR", Status = "Close" }); 
       } 
       else if (line.Contains("B")) 
       { 
        users.Add(new User() { MachineName = "LBSTR", Status = "Open" }); 
       } 
      } 
     } 
    } 
} 

public class User 
{ 
    public string MachineName {set;get;} 
    public string Status {set;get;} 
} 

XAML:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <DockPanel Margin="10"> 
     <StackPanel DockPanel.Dock="Right" Margin="10,0,0,0"> 
      <Button Name="btnCheckStatus" Click="btnCheckStatus_Click">Check Status</Button> 

     </StackPanel> 
     <DataGrid Name="lbUsers" ></DataGrid> 
    </DockPanel> 
</Grid> 

Quand je lance première fois en cliquant sur le statut de vérification, une ligne est obtenir ajouté avec le nom de la machine et état du fichier. For a first click

Pour le 2ème et cliquez sur le même bouton, une nouvelle ligne est ajoutée pour la même machine.

Further Check status

Je veux juste savoir comment puis-je mettre à jour le statut seul au nom de la machine correspondante car cette méthode crée une nouvelle ligne à chaque fois que je vérifier l'état du fichier dans la machine à distance.? S'il vous plaît laissez-moi savoir s'il y a un moyen ou un article en ligne qui m'aide à identifier la solution.

+0

Qu'avez-vous essayé jusqu'à présent? Je ne vois rien dans votre code pour essayer de trouver et de mettre à jour une ligne existante - il suffit d'appeler Ajouter à chaque fois. –

+0

Vous avez donc déjà décrit dans votre question ce que vous devez faire - trouvez dans votre 'ObservableCollection' si l'objet que vous essayez de mettre à jour existe, et si c'est le cas, changez le statut de cet élément. Maintenant, il s'agit de le coder. Ainsi, au lieu de 'users.Add()', vérifiez d'abord si 'users' a l'élément en question, et si c'est le cas, mettez-le simplement à jour au lieu de l'ajouter à la liste. – Sach

Répondre

0

Ainsi, comme l'a dit Sach, modifiez votre btnCheckStatus_Click à quelque chose comme ceci:

private void BtnCheckStatus_Click(object sender, RoutedEventArgs e) 
    { 
     var fileStreamStatus = new FileStream(@"\\LBSTR\c$\temp\range.dat", FileMode.Open, FileAccess.Read); 
     using (var streamReader = new StreamReader(fileStreamStatus, Encoding.UTF8)) 
     { 
      string line; 
      while ((line = streamReader.ReadLine()) != null) 
      { 
       var user = new User { MachineName = "LBSTR" }; 

       if (line.Equals("A")) 
        user.Status = "Close"; 

       else if (line.Contains("B")) 
        user.Status = "Open"; 

       var existingUser = _users.FirstOrDefault(u => u.MachineName.Equals(user.MachineName)); 

       if (existingUser != null) 
       { 
        existingUser.Status = user.Status; 
        return; 
       } 

       _users.Add(user); 
      } 
     } 
    } 

Notez que cette ligne: complexe

var existingUser = _users.FirstOrDefault(u => u.MachineName.Equals(user.MachineName)); 

est O (n). Donc, si vous deviez l'exécuter très souvent, vous devriez considérer une collection hachée au lieu du simple ObservableCollection.

Et aussi pour DataGridCell pourrait mettre à jour la valeur - votre classe utilisateur doit mettre en œuvre l'interface INotifyPropertyChanged comme ceci:

public class User : INotifyPropertyChanged 
{ 
    private string _machineName; 
    private string _status; 

    public string MachineName 
    { 
     set 
     { 
      if (!value.Equals(_machineName)) 
      { 
       _machineName = value; 
       NotifyPropertyChanged(); 
      } 
     } 
     get { return _machineName; } 
    } 

    public string Status 
    { 
     set 
     { 
      if (!value.Equals(_status)) 
      { 
       _status = value; 
       NotifyPropertyChanged(); 
      } 
     } 
     get { return _status; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+0

Merci Taras pour votre aide à ce sujet. Cela a bien fonctionné. Si cela ne vous dérange pas, pourriez-vous me dire comment ajouter une couleur à la colonne Statut comme si elle est ouverte puis verte et si elle est fermée, puis rouge? J'ai cherché et la plupart des exemples sont à l'aide de XAML (DataGridTextColumn), mais voici la colonne déjà créée avec l'aide de la classe User. – Siva

+0

Glag que cela vous a aidé, n'oubliez pas de marquer la réponse comme acceptée. Je pourrais vous aider avec votre autre problème mais comme il n'est pas lié à ce sujet je ne devrais pas poster le code ici. Vous avez essentiellement besoin d'une sorte de StatusToBrushConverter (qui implémente IValueConverter) pour convertir votre valeur de chaîne à un pinceau et un style DataGridCell très simple avec juste un setter pour la propriété d'arrière-plan liée à votre accessoire Status en utilisant ce convertisseur. – Taras

+0

Merci Taras. Je l'ai compris. Je souhaite que je puisse UpVote plus d'une fois mais je ne pourrais pas Depuis que je n'ai pas la réputation de vous honorer. N'importe comment merci pour votre aide à ce sujet. – Siva