MVVM Light を使用して WPF でデータ視覚化コードを作成しています。ここにフラグメントがあります:
<Window x:Class="EventBlockVisualization.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
Title="MainWindow"
mc:Ignorable="d ignore"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ItemsPanelTemplate x:Key="GraphRowItemsPanelTemplate">
<StackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Window.Resources>
<Grid IsSharedSizeScope="True">
<ScrollViewer Margin="8" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
<ItemsControl x:Name="GraphItemsControl" Margin="8" ItemsSource="{Binding VibeEvents, Mode=OneTime}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="NameWidthSizeGroup" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="NameTextBlock" Text="{Binding Name}" Grid.Column="0" Margin="4,0"/>
<ItemsControl x:Name="GraphRowItemsControl" ItemsSource="{Binding VibeEventViewModels, Mode=OneTime}" ItemsPanel="{DynamicResource GraphRowItemsPanelTemplate}" Grid.Column="1" Margin="4,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" VerticalAlignment="Center" Height="10">
<TextBlock x:Name="FGTitleTextBox" Text="{Binding FGTitle}" Visibility="Collapsed"/>
<Button Margin="1,0,0,0" Width="{Binding LengthInSeconds}" HorizontalAlignment="Left" Background="{Binding BackgroundColor}" BorderBrush="#FF2186A1">
<Button.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock FontWeight="Bold" Text="{Binding FGTitle}"/>
<TextBlock Text="{Binding LengthText}"/>
</StackPanel>
</ToolTip>
</Button.ToolTip>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
ItemsControl.ItemTemplate
DataTemplate
Expression Blend でより簡単に設計できるように、中央を交換してユーザー コントロールにしたいと考えています。
MVVM Light にユーザー コントロールを含む単純なサンプルは見つかりませんが、いくつかのチュートリアル記事があります。たとえば、MVVM Instantiation Approaches (Option 6) では、Paul Stovell が MVVM Light で UserControl の ViewModel にバインドすることを提案しています。
<UserControl ...>
<UserControl.Resources>
<ViewModelLocator x:Key="ViewModelLocator"/>
</UserControl.Resources>
<TextBox Text="{Binding Source={DynamicResource ViewModelLocator}, Path=CalculatorViewModel...}" />
ロケーターがダミー データでいっぱいの ViewModel を提供できるため、Expression Blend で UserControl を設計している場合、これはうまく機能します。しかし、実行時に何が起こるか。そのバインディングは、メイン ViewModel のコレクションによって提供される UserControl の ViewModel クラスのインスタンスでどのように上書きされますか? 設計時に MainWindow でも同じ問題が発生します。MainWindow のルック アンド フィールで Expression Blend を使用している場合、そのバインディングは、デザイン タイムのメイン ViewModel のコレクションによって提供される UserControl の ViewModel クラスのインスタンスでどのように上書きされますか?
すでにこれに触れている多くの質問と回答があります。
https://stackoverflow.com/a/3334780/575530で akjoshi は、メインの ViewModel が UserControl の ViewModel のインスタンスを保持することを提案しています。しかし、UserControl 自体を設計しているときに、それはどのように機能しますか?
https://stackoverflow.com/a/9910298/575530で、タムは「データコンテキストを開いたままにして、このコントロールを使用しているコントロールにバインドできるようにしたい」と指摘し、次のコメントで SoMoS は必要なことを追加します「バインドされたプロパティのViewModelにプロパティを作成し、誰かがコントロールの1つのプロパティを変更したい場合(サブコントロールが有効になっているなど)、ビューモデルを通過する必要があります」。それは有望ですが、MainViewModel のバインド可能な UserControlViewModels のコレクションの代わりに何をすべきかわかりません。
https://stackoverflow.com/a/6340668/575530で Ehsan Ershadi は、「MVVM Light ViewModelLocator は静的プロパティであり、ユーザー コントロールの複数のインスタンスをインスタンス化する場合に、UserControles に使用することはお勧めできません」と示唆しています。同じ共通の ViewModel があるため、それらはすべて同じように動作しますが、これは、プロジェクト全体で 1 回使用することにした場合に備えて、UserControl に必要なものではありません。」そして、「この問題を回避するには、たとえば、すべてのプロパティを非静的にすることで ViewModelLocator を変更する必要がある」と述べています。それがどのように役立つかわかりません。
https://stackoverflow.com/a/2637830/575530の後のコメントで、Jon Mitchell は「MVVM はユーザー コントロールの作成には理想的ではないようです」と述べています。それが正しくないことを願っています。
対照的に、ページの代わりに UserControl を使用する必要があるのはいつですか? dthrasher は、「WPF MVVM フレームワークの多くは、ネストされた UserControls を使用してページを構成することを優先して、NavigationWindow コントロールと Page コントロールの使用を避けているように見える」と述べています。つまり、UserControls は MVVM では一般的なデバイスです。
https://stackoverflow.com/a/1798649/575530で、Reed Copsey はサンドボックスに、「UserControls は、プロパティを公開し、DataBinding を使用することで、常に含まれているコントロールと通信できることを思い出させます。MVVM スタイルをすべての面で保持するため、これは非常に優れています。 " そして、「包含コントロールは、プロパティを使用して2つのユーザーコントロールの2つのプロパティをリンクし、きれいな境界を維持できます」しかし、Expression BlendでUserControlを設計しているときに、これがどのように役立つかわかりません。
ビューに DataTemplates の代わりにUserControls を使用する必要がありますか? Rachel は、DataTemplate にコードをカット アンド ペーストする前に、Expression Blend を使用して UserControl を設計することについて言及しています。次に、内容をコピーして DataTemplate に貼り付けます」
このエッセイの長さの質問で申し訳ありません!MainWindow のコレクション内のアイテムのビジュアルになる予定の UserControl を設計するときに MVVM Light を使用する方法、特に 3 つのバインディング (ランタイム ビュー モデル、メインのデザイン タイム ビュー モデル) をセットアップする方法について混乱しています。ウィンドウとそのユーザー コントロールのインスタンス化、および分離されたユーザー コントロールの設計時のビュー モデル。