私はMVVMを初めて使用し、以下のシナリオでヘルプが必要です。
ビューにスタックパネルを追加しましたが、viewmodelを使用してこのスタックパネルに動的にいくつかのコントロールを追加する必要があります。このために、ビューモデルにスタックパネルのハンドルが必要です。ビューモデルでスタックパネルにアクセスする方法を教えてください。
他のブログで、Dependencyプロパティを使用して実行できることを読みました。しかし、それでも私はこの問題を解決する方法を見つけることができません。
私はMVVMを初めて使用し、以下のシナリオでヘルプが必要です。
ビューにスタックパネルを追加しましたが、viewmodelを使用してこのスタックパネルに動的にいくつかのコントロールを追加する必要があります。このために、ビューモデルにスタックパネルのハンドルが必要です。ビューモデルでスタックパネルにアクセスする方法を教えてください。
他のブログで、Dependencyプロパティを使用して実行できることを読みました。しかし、それでも私はこの問題を解決する方法を見つけることができません。
最初に注意すべき点がいくつかあります。MVVMパターンのViewModelの目的は、ビューからの分離を提供することです。したがって、ViewModelには、ビュー自体やビューに含まれるコントロールについての知識がないはずです。次に、ビューをViewModelのプロパティにバインドする必要があります(ViewModelがビューのDataContextとして機能することを理解した上で)。通常、コントロールのItemsSourceプロパティをViewModelのコレクションにバインドします。ただし、StackPanelはItemsSource依存関係プロパティを実装していないことに気付くでしょう。代わりに、StackPanelの代わりにItemsControlを使用してください。さらに明確にするために、MVVMパターンとバインディングメカニズムに関する追加の読み物をお勧めします。
バックラッシュに完全に同意しました。ViewModelとViewの結合が多すぎるようです。インターネット上にはたくさんのリソースがありますが、私が好むものは次のとおりです。
私は以前、ユーザーコントロールを使用してこれを行いました。StackPanelのコントロールに動的に必要なオブジェクトのコレクションがあります。任意のコントロールでそれを行うこともできます...この例ではTextBlockを使用します。
スタックパネルにラップしたいコントロールを使用してデータテンプレートを作成します:(MyTextはコレクションのオブジェクトのプロパティです...以下を参照してください)
<DataTemplate x:Key="MyTemplate">
<Grid Margin="0">
<StackPanel>
<TextBlock Text="{Binding Path=MyText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
次に、ItemsControlを使用してオブジェクトのコレクションにバインドすることが重要です:(コレクションはviewModelにあります)
<ItemsControl
ItemsSource="{Binding ACollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemTemplate=" {StaticResource MyTemplate}" Background="Transparent">
</ItemsControl>
したがって、たとえば、「ACollection」に3つのアイテムがある場合、3つのTextBlockが互いに積み重ねられ、コレクションに5つある場合、5つのTextBlockなどがあります。
助けてくれてありがとう、ここで私は問題を解決しました
ビューモデルでは、FrameWorkElementタイプのObservableCollectionを作成しました。これは、実行時に決定される他のコントロールを保持できます。コントロールは、テキストボックスまたはボタンにすることができます。
Public ObservableCollection < FrameWorkElement > Test
{
get{....} set{...}
}
これで、他のコントロールをテストに追加/設定できます
Tets.Add(new TextBox()); Or Button , this will be decided at runtime.
次に、この「テスト」をItemsControlにバインドします。
<ItemsControl x:Name="itemsControl" ItemsSource={Biding Test}>
</ItemsControl>