MVVMのObjectDataproviderは必要ありませんか?
-
01-10-2019 - |
質問
CashFlowViewModel、CashFlowModelの3つのクラスのみで、シンプルなMVVMを作成しました。
Infragisticの9.1 Xamdatapresenter(またはXamdatagrid)を使用しています。
<igDP:XamDataPresenter Name="xamDataPresenter1" DataSource="{Binding Source={StaticResource CashFlowData}}">
<ObjectDataProvider x:Key="CashFlowData" ObjectType="{x:Type ViewModel:CashflowViewModel}" MethodName="GetCashFlows" />
私のviewmodel内:
public ObservableCollection<CashflowModel> GetCashFlows()
{
return new ObservableCollection<CashflowModel>() { ... };
}
ViewModelはこれによって表示されるように接続されています:
this.DataContext = new CashflowViewModel();
グリッドをObjectDataproviderに接続している限り、完全に動作しています。しかし、代わりにビューモデル内のプロパティに接続できることを望みました。
Infragisticsによれば、私がしなければならないのはこれだけです:
<igDP:XamDataGrid DataSource="{Binding Path=ViewModelCollection}"/>
しかし、この場合、グリッド内の行を表すために別のViewModelのコレクションにバインドする必要があるようです。そして、それは私が混乱するところです。
私はこれを試しましたが、それは機能しません:
<igDP:XamDataPresenter Name="xamDataPresenter1" DataSource="{Binding Path=CashFlows}">
ビューモデル内:
public ObservableCollection<CashflowDataGridViewModel> CashFlows
{
get
{
return new ObservableCollection<CashflowDataGridViewModel>();
}
}
しかし、2番目のViewModel(CashFlowDatagridViewModel)を作成するにはどうすればよいですか?
この2番目のviewmodelにこのproprtyを追加しようとしました。
public CashflowModel CashFlow
{
get
{
return new CashflowModel() {...};
}
}
しかし、私の見解に示されているのは、実際のCashFlowModelクラスの基礎となるヘッダーのない「CashFlow」列ヘッダーだけです。
解決
ViewModelのプロパティにビューをバインドできるようにするには、DataContextをViewModelのインスタンスに設定する必要があります。私が一般的にしているのは、私の見解のために、コードビハインドのコンストラクターに次の行を含めることです。
this.DataContext = new SomeAwesomeViewModel();
また、さまざまなコントロールグループに異なるViewModel(grid.datacontext、stackpanel.datacontextなど)を使用する場合にコンテナのDataContextを設定することもできます。
DataContextセットを設定したら、そのViewModelのプロパティにバインドできるはずです。
アップデート
これがあなたを動かすためのサンプルコードを少し紹介します。
public class CashFlowViewModel
{
public ObservableCollection<FlowViewModel> DataGridData
{
get...
}
}
これが、Datagridのデータを提供するプロパティです。さて、ここに何がありますか FlowViewModel
クラスはどのように見えるかもしれません。
public class FlowViewModel
{
decimal flowAmount;
public decimal FlowAmount
{
get { return flowAmount; }
set
{
if(flowAmount == value)
return;
flowAmount = value;
NotifyPropertyChanged("FlowAmount");
}
}
.
.
.
private void NotifyPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}