2017-11-10 5 views
0

私はPrism WPFを初めて使用し、それがどのように動作し、アプリケーションを構築するかを基本的に理解しています。OnNavigatedToメソッドを使用してコンボボックスバインドを空にする

特に、 'OnNavigatedTo'メソッドを使用して、ビューのコントロールにデータをバインドする際に問題があります。

アプローチ1

私は顧客を埋めるためにリポジトリを呼び出すときしかし、ビュー内のコンボボックスが空で、「OnNavigatedTo」メソッドがコンストラクタの後に呼び出されることを理解しています。

のViewModel:

public class ViewAViewModel : BindableBase, INavigationAware 
{ 
    private readonly IRegionManager _regionManager; 
    private readonly IRepository _repository; 

    public List<Customer> Customers { get; set; } 

    public ViewAViewModel(IRepository repository, IRegionManager regionManager) 
    { 
     _repository = repository; 
     _regionManager = regionManager; 
     Customers = new List<Customer>(); 
    } 

    private string _selectedCustomer; 
    public string SelectedCustomer 
    { 
     get { return _selectedCustomer; } 
     set { SetProperty(ref _selectedCustomer, value); } 
    } 

    public void OnNavigatedTo(NavigationContext navigationContext) 
    { 
     Customers = _repository.GetCustomers(); 
    } 

    public bool IsNavigationTarget(NavigationContext navigationContext) 
    { 
     return true; 
    } 

    public void OnNavigatedFrom(NavigationContext navigationContext) 
    { 

    } 
} 

ビュー:

<UserControl x:Class="ModuleA.Views.ViewA" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:prism="http://prismlibrary.com/"    
      prism:ViewModelLocator.AutoWireViewModel="True"> 
    <Grid> 
     <StackPanel> 
      <ComboBox ItemsSource="{Binding Customers}" DisplayMemberPath="Name" SelectedValuePath="Id" SelectedValue="{Binding SelectedCustomer}"></ComboBox> 
     </StackPanel>  
    </Grid> 
</UserControl> 

私は/コンストラクタ 'を通してお客様を埋める初期化する場合は、モジュールがモジュールに追加されたときに、結合コンボボックスは、しかし、正常に動作しますブートストラップのカタログ 'Customers'リポジトリメソッドは不必要に呼び出されます。私はこれが理想的ではないと思います。

アプローチ2

私は '得意先' on 'にRaisePropertyChanged' を使用する場合は、コンボボックスにデータをバインドすることは正常に動作します。

のViewModel:

public class ViewAViewModel : BindableBase, INavigationAware 
{ 
    private readonly IRegionManager _regionManager; 
    private readonly IRepository _repository; 
    private List<Customer> _customers; 

    public List<Customer> Customers 
    { 
     get { return _customers; } 
     set 
     { 
      _customers = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public ViewAViewModel(IRepository repository, IRegionManager regionManager) 
    { 
     _repository = repository; 
     _regionManager = regionManager; 
     _customers = new List<Customer>(); 
    } 

    private string _selectedCustomer; 
    public string SelectedCustomer 
    { 
     get { return _selectedCustomer; } 
     set { SetProperty(ref _selectedCustomer, value); } 
    } 

    public void OnNavigatedTo(NavigationContext navigationContext) 
    { 
     Customers = _repository.GetCustomers(); 
    } 

    public bool IsNavigationTarget(NavigationContext navigationContext) 
    { 
     return true; 
    } 

    public void OnNavigatedFrom(NavigationContext navigationContext) 
    { 

    } 
} 

は取るべき正しいアプローチアプローチ2ですか?あるいは私は何かを逃している。

ありがとうございます。

+0

2番目のアプローチは正しいです。 'Customers'プロパティはバインディングソースであるため、バインディングにターゲットを更新する必要があることを通知するために、' PropertyChanged'イベントを発生させる必要があります。これは実際には一般的なデータバインディングのトピックですが、特にPrismやナビゲーションに関しては何の関係もありません。 – dymanoid

+0

ありがとうございます、誤った分類のためにお詫び申し上げます。私の最初の質問です。 –

答えて

0

RaisePropertyChangedを呼び出さないため、最初の方法が間違っています。 コンストラクタでは、新しい空のリストをCustomersプロパティに割り当てて、コンボボックスが空になるようにします。

OnNavigatedToメソッドでは、PopulatedリストをCustomersプロパティに割り当てますが、CustomersプロパティはRaisePropertyChangedを呼び出さないため、ビューは変更を認識しません。

これは、一般的に正しいアプローチである2番目のアプローチとまったく同じように修正できます。

もう1つの解決策は、OnNavigatedToに移入する代わりにコンストラクタにリストを移入することです。この場合、CustomersプロパティはRaisePropertyChangedを呼び出す必要はありません。ビューは更新された要素で既に構築されるからです。

これは、ビューにいるときにCustomersプロパティがもう変更されない場合にのみ意味があります。

+0

第3のアプローチがあることに注目する価値があります。 'List 'の代わりに 'ObservableCollection 'を使うことができます。これはコンストラクタで作成し、後でデータで埋め込むことができます。ビューは 'CollectionChanged'イベントをリッスンするので更新されます。 – dymanoid

+0

お返事ありがとうございます。 上記のシナリオで「得意先」とは、一方向のバインディングソース、つまりビューでは変更されません。 アプリケーションパフォーマンスの観点から、コンストラクタを介して 'Customers'データを読み込むのは理想的ではありませんが、正しいですか?上の質問で述べたように、モジュールがモジュールカタログにロードされると、そのモジュール内のビューモデルのコンストラクタが呼び出され(データのロードなど)、そのビューに移動するとコンストラクタが再び呼び出されます。たぶん私は拘束力のある作品やプリズムということを誤解しているかもしれません。 –

関連する問題