WPF - ObSerableCollectionsを使用してDataGridの新しい行の代わりに既存の行値を更新する -- c# フィールド と wpf フィールド と xaml フィールド と datagrid フィールド と observablecollection フィールド 関連 問題

WPF - Updating the existing ROW values instead of a new Row in DataGrid using ObserableCollections












0
vote

問題

日本語

私はWPFに慣れています、そして私は時間の節約目的のための簡単な道具を構築するための基本的なことを学びようとしています。ここではリモートファイルを読み込んでステータスを取得し、マシン名とファイルのステータスを使用してDataGridの更新を行います。

下記は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(@"\LBSTRc$ emp ange.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>

チェックステータスをクリックして初めて実行すると、ファイルのマシン名とステータスで行が追加されます。 最初のクリック

2ndをクリックして同じボタンをクリックすると、同じマシンに新しい行が追加されました。

さらにチェックステータス

リモートマシンのファイルのステータスを確認するたびに、ステータスだけを対応するマシン名に更新する方法を知りたいです。解決策を特定するのに役立つ方法やオンライン記事があるかどうか教えてください。

英語

I'm new to WPF and I'm trying to learn the basic things to build a simple tool for a time saving purpose. Here I'm trying to read a remote file to get the status and updating the datagrid with machine name and status of the file.

Below is the CS code:

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(@"\LBSTRc$ emp ange.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> 

When I run first time by clicking the Check Status, a Row is getting added with machine name and status of the file. For a first click

For the 2nd and further click the same button, a new row is getting added for the same machine.

Further Check status

I just want to know how can I update the status alone to the corresponding machine name since this method is creating a new row every time when I checking the status of the file in remote machine.? Please let me know if there is a way or online article that helps me to identify the solution.

</div
              
   
   

回答リスト

0
 
vote
vote
ベストアンサー
 

SOCHと同じように、あなたのbtncheckstatus_clickをこのようなものに変更する:

<事前> <コード> private void BtnCheckStatus_Click(object sender, RoutedEventArgs e) { var fileStreamStatus = new FileStream(@"\LBSTRc$ emp ange.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); } } }

この行:

<事前> <コード> var existingUser = _users.FirstOrDefault(u => u.MachineName.Equals(user.MachineName));

はO(n)錯体です。それであなたがそれを非常に頻繁に実行しなければならなかったのであれば - あなたは簡単なObservableCollectionの代わりにいくつかのハッシュコレクションを考慮する必要があります。

およびDataGridCellの場合も、値を更新できます - ユーザークラスは次のようなinotifyPropertyChangedインタフェースを実装する必要があります。

<事前> <コード> 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)); } }
 

So as Sach said, modify your btnCheckStatus_Click to something like this:

    private void BtnCheckStatus_Click(object sender, RoutedEventArgs e)     {         var fileStreamStatus = new FileStream(@"\LBSTRc$ emp ange.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);             }         }     } 

Note that this line:

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

is O(n) complex. So if you had to execute that very often - you should consider some hashed collection instead of simple ObservableCollection.

And also for DataGridCell could update the value - your User class should implement INotifyPropertyChanged interface like this:

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));     } } 
</div
 
 
       
       

関連する質問

169  OBSERVABLECOLLECTION ITの中の項目が変更されていない(InotifyPropertyChangedさえ)  ( Observablecollection not noticing when item in it changes even with inotifyprop ) 
誰かがこのコードが機能しない理由を知っていますか: <事前> <コード> public class CollectionViewModel : ViewModelBase { public ObservableCollection<EntityVi...

0  Windows PhoneのXAMLで展望具合のコレクションをバインドする  ( Binding observable collection in xaml in windows phone ) 
単純なWindows Phone 7ページのPivotItemに含まれるリストボックスのItemsSourceを宣言的に設定するのに問題があります。 ItemsSourceを後にあるコードに正常に設定できます。 これは、バインドしたいObservableCol...

1  クラスをObservableCollectionに変換することはできません  ( Cannot convert class to observablecollection ) 
クラス<コード> AllStock を<コード> ObservableCollection<AllStock> stockList に変換しようとしていますが、次のエラーが発生します。 'System.Collections.ObjectModel.Col...

0  ObservableCollectionの可視性イヴァリコンサービス<T> [重複]  ( Visibility ivalueconverter for observablecollectiont ) 
この質問はすでにここで回答を持っています EmptyListTovisibilityConverter (6回答) ...

1  Windows Phone 7データバインディングタイミング問題  ( Windows phone 7 data binding timing issues ) 
私は、絶縁されたストレージに永続化されている観察可能なコレクションのローカルの "データベース"を持つWindows Phone 7アプリケーションを持っています。アプリケーションが最初に実行されると、データが存在するかどうかを確認して、データがない場合はWC...

3  WPF DataGrid - Timeseries W / MultiBindingを組み合わせると、変更通知が失われます。どうして?  ( Wpf datagrid combining timeseries w multibinding lose change notification wh ) 
2つのobservableCollectionを持つクラスを持っています&lt; timevalue&gt。ここで、timevalueは、(inotifyPropertyChangedを介して)変更通知とのカスタムDateTime /値のペアリングです。私は...

0  動的に生成されたコレクションをフィルタリングするためのLINQ WHERE句を使用する方法  ( How to use linq where clause for filtering the collection having dynamically gen ) 
SilverlightアプリケーションのLINQ WHERE句を使用してObservableCollectionをフィルタリングする必要があります。 オブジェクトタイプは、以下のURLで提供されているメソッドを使用して動的に作成されます。 http://m...

1  私のC#コレクションベースのコードを最適化するためにどのようなLINQ演算子/メソッドを使用することができますか?  ( What more linq operators methods can i use to optimize my c sharp collections ba ) 
方法があります(<コード> LINQ を使用して)私は以下のコードを最適化することができます。このコードは、変数 mySecondCollection の項目を比較することによって、変数 myFirstCollection の項目を追加、削除して更新します。...

1  WPF ListView SelectionChangedイベントハンドラからのObservableCollectionを参照する方法  ( How to reference observablecollection from wpf listview selectionchanged event h ) 
WPFアプリでは、ObservableCollection ShQuCollection を介して接続されているListViewがあります。 <事前> <コード> <ListView Name="ShSelList" ItemsSource="{Bind...

3  コレクションの項目のサブセットのみを使用してコンボへのWPFバインディング  ( Wpf binding to a combo using only a subset of a collections items ) 
コレクションのオブジェクトの選択しか使用して、コンボボックスに2つのバインディングを設定しようとしています。現在、すべてが致命的なものにバインドしたいのであれば、すべて問題なく動作しますが、以下の例のクラスの例では、Active = Trueのアイテムを表示し...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有