de-vraag
  • 質問
  • タグ
  • ユーザー
通知:
報酬:
登録
登録すると、質問に対する返答やコメントが通知されます。
ログイン
すでにアカウントをお持ちの方は、ログインして新しい通知を確認してください。
追加された質問、回答、コメントには報酬があります。
さらに
ソース
編集
 Leone510
Leone510
質問

WPF MVVM:ObservableCollectionの変更をUIに反映させる方法

私はWPFが比較的新しく、MVVMで作業しているアプリケーションを構築するために、MVVMパターンとObservableCollectionでのデータバインディングのしくみを理解しようとしています。メインウィンドウを持つアプリケーションのサンプルを作成しました。ここでは、ユーザーがどのボタンを押すかに応じて、異なるビュー(UserControl)が表示されます。一般的な考え方は、ユーザがデータベースからいくつかの要素のデータにアクセスし(例:顧客、製品など)、既存の要素を新規に追加したり編集したり削除したりできるようになるというものです。

So, there is a CustomerView, with its CustomerViewModel, and a ProductView, with its ProductViewModel respectively. Also, there are two classes (Customer.cs & Product.cs) that represent the Models. The structure of the project is displayed here.

MainWindow.xamlは次のとおりです。


    
        
    
    
        
    



    
        
        
    

    
        

そしてMainWindow.xaml.csの背後にあるコード:

public partial class MainWindow : Window
{
    public CustomerViewModel customerVM;
    public ProductViewModel productVM;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnCustomers_Click(object sender, RoutedEventArgs e)
    {
        if (customerVM == null)
        {
            customerVM = new CustomerViewModel();
        }
        this.DataContext = customerVM;
    }

    private void btnProducts_Click(object sender, RoutedEventArgs e)
    {
        if (productVM == null)
        {
            productVM = new ProductViewModel();
        }
        this.DataContext = productVM;
    }
}

最後に、CustomerView.xamlは次のとおりです。


    
    



    
        
        
        
    

    
        
    

    
        
            
            
        

        
        

        
            
                
                
            
            
                
                
            
            
                
                
            
        
    

    
        

そしてCustomerViewModel.cs:

public class CustomerViewModel : ObservableCollection
{
    public CustomerViewModel()
    {
        LoadCustomers();
    }

    private void LoadCustomers()
    {
        for (int i = 1; i <= 5; i++)
        {
            var customer = new Customer()
            {
                Id = i,
                FirstName = "Customer_" + i.ToString(),
                LastName = "Surname_" + i.ToString()
            };
            this.Add(customer);
        }
    }

    public void AddNewCustomer(int id)
    {
        var customer = new Customer()
        {
            Id = id,
            FirstName = "Customer_" + id.ToString(),
            LastName = "Surname_" + id.ToString()
        };
        Add(customer);
    }
}

Please note that the ProductView.xaml & ProductViewModel.cs are similar. Currently, when the user presses the "Customers" or the "Products" button of the MainWindow, then the respective View is displayed and the collections are loaded according to the LoadCustomers (or LoadProducts) method, which is called by the ViewModel's constructor. Also, when the user selects a different object from the ComboBox, then its properties are displayed correctly (i.e. Id, Name, etc.). The problem is when the user adds a new (or deletes an existing) element.


Question 1: Which is the correct and best way to update a changed Observable Collection of an element and reflect its changes in the UI (Combobox, properties, etc.)?

Question 2: During testing this project I noticed that the constructor of the ViewModels (consequently the LoadCustomers & LoadProducts method) are called twice. However, it is only called when the user presses the Customers or the Products button respectively. Is it also called via the XAML data binding? Is this the optimum implementation?

0 2018-12-03T15:26:54+00:00 4
プログラミング
wpf
c#
xaml
mvvm
observablecollection
BradleyDotNET
3日 12月 2018 в 3:35
2018-12-03T15:35:12+00:00
さらに
ソース
編集
#85313932

あなたの最初の質問は基本的にはUXの質問です、正しいまたは "最良の"方法はありません。あなたは間違いなくある種の ItemsControl を使うことになるでしょう、しかしそれはあなたがあなたのユーザーがそれとどのようにやり取りしたいかに大きく依存します。

2番目の質問に、あなたはあなたのコードにいくつかの間違いがあります:

  1. Instantiates a new view model, apart from the one that the main application created

  2. Grid DataContext="{StaticResource ResourceKey=customerVM}" Then uses this "local" view model, ignoring the inherited one from the main application

そのため、コンストラクタが2回起動し、2つのインスタンスを構築しているのがわかります。ローカルVMを排除し、グリッドにDCを割り当てないでください。その他の問題

  • The DataContext assignment is total unnecessary, by virtue of being in the data template it's data context is already set up
  • Yuck, you should have a "MainViewModel" with a property that this uses. Don't make it be the whole data context

  • Lack of commands for your button clicks (related to the bullet above)

2
0
BradleyDotNET
3日 12月 2018 в 3:35
2018-12-03T15:35:12+00:00
さらに
ソース
編集
#85313933

あなたの最初の質問は基本的にはUXの質問です、正しいまたは "最良の"方法はありません。あなたは間違いなくある種の ItemsControl を使うことになるでしょう、しかしそれはあなたがあなたのユーザーがそれとどのようにやり取りしたいかに大きく依存します。

2番目の質問に、あなたはあなたのコードにいくつかの間違いがあります:

  1. Instantiates a new view model, apart from the one that the main application created

  2. Grid DataContext="{StaticResource ResourceKey=customerVM}" Then uses this "local" view model, ignoring the inherited one from the main application

そのため、コンストラクタが2回起動し、2つのインスタンスを構築しているのがわかります。ローカルVMを排除し、グリッドにDCを割り当てないでください。その他の問題

  • The DataContext assignment is total unnecessary, by virtue of being in the data template it's data context is already set up
  • Yuck, you should have a "MainViewModel" with a property that this uses. Don't make it be the whole data context

  • Lack of commands for your button clicks (related to the bullet above)

2
0
Christopher
3日 12月 2018 в 3:33
2018-12-03T15:33:45+00:00
さらに
ソース
編集
#85313930

MVVMのリストで必要な変更通知は3種類あります。

  1. リストアイテムのすべてのプロパティの通知を変更します。
  2. インスタンス全体を置き換える必要がある場合に備えて、リストを公開しているプロパティの変更通知(3が原因で一般的です)
  3. コレクションに要素が追加または削除された場合の通知の変更それがObservableCollectionが気を配る唯一のことです。残念ながらAddrangeオプションはありませんので、一括操作ではNotificationsでGUIをスワップします。それがNrです。 2があります。

高度なオプションとして、生のCollectionではなくCollectionViewを公開することを検討してください。 WPFのGUI要素は生のコレクションにはバインドされず、CollectionViewのみにバインドされます。しかし、あなたが彼らに手渡さなければ、彼らは彼ら自身を創造するでしょう。

1
0
Christopher
3日 12月 2018 в 3:33
2018-12-03T15:33:45+00:00
さらに
ソース
編集
#85313931

MVVMのリストで必要な変更通知は3種類あります。

  1. リストアイテムのすべてのプロパティの通知を変更します。
  2. インスタンス全体を置き換える必要がある場合に備えて、リストを公開しているプロパティの変更通知(3が原因で一般的です)
  3. コレクションに要素が追加または削除された場合の通知の変更それがObservableCollectionが気を配る唯一のことです。残念ながらAddrangeオプションはありませんので、一括操作ではNotificationsでGUIをスワップします。それがNrです。 2があります。

高度なオプションとして、生のCollectionではなくCollectionViewを公開することを検討してください。 WPFのGUI要素は生のコレクションにはバインドされず、CollectionViewのみにバインドされます。しかし、あなたが彼らに手渡さなければ、彼らは彼ら自身を創造するでしょう。

1
0
質問の追加
カテゴリ
すべて
技術情報
文化・レクリエーション
生活・芸術
科学
プロフェッショナル
事業内容
ユーザー
すべて
新しい
人気
1
Денис Анненский
登録済み 2日前
2
365
登録済み 6日前
3
True Image
登録済み 6日前
4
archana agarwal
登録済み 1週間前
5
Maxim Zhilyaev
登録済み 1週間前
© de-vraag :年
ソース
stackoverflow.com
ライセンス cc by-sa 3.0 帰属