2

TabControlオブジェクトのコレクションを提示しているがありますFoo(それぞれを介してFooViewModel)。タブアイテムのリストの最後に、何もモデル化しないが、新しいモデルアイテムを作成し、クリックするとコレクションに追加する偽のタブアイテムが必要です。

概念が明確でない場合、実際の例はInternetExplorerのタブです。これにはn+1タブアイテムがあります。nページコンテンツがあり、最後のアイテムは新しい「実際の」タブを追加します。

MVVMでこのタイプの相互作用をモデル化する正しい方法(ある場合)は何ですか?私が考えたオプションは次のとおりです。

  • ビューモデルの一部にします。コントロールがバインドされているコレクションの最後にIEnumerable<FooViewModel> Foos、「新しいアイテム」センチネルを追加し、「実際のfooまたは新しいfooセンチネル」ロジックをビューモデルに構築します。

  • 完全にビューの一部にします。テンプレートを再作成(および/またはサブクラス)TabControlして、すべての実際のアイテムを表示し、コマンドを呼び出して新しいアイテムを作成および挿入するボタンも表示します。

最初のオプションは、ビューの詳細がビューモデルにリークしているように、最初は間違っているように感じます(「新規追加Foo」は一般的なコマンドである可能性が高く、一部のビューではタブリストから呼び出し可能にしたくない場合があります)。ただし、初期化プロセスでは「半構築」をモデル化する必要があるため、ある程度の意味がありますFoo。したがって、「まだ存在しない」のモデルはFooそれほど遠くないように見えます。

2番目の部分は、多くの作業のように見え、また簡単に失敗するようです(他のタブのように見えて感じることが望ましいと仮定します)。

しかし、私はMVVMを初めて使用します。確かにこれはかなり頻繁に出てきます。多分私は完全に何かが欠けています。それに対処するための伝統的な方法は何ですか?

4

3 に答える 3

1

MVVMパターンの主要なテナントのいくつかは次のとおりです。

  • テスト容易性-ビューを可能な限りシンプルにし、ロジックをビューモデルに移動することで、単体テストでテストできるロジックの量を増やします。
  • Designer- Support-モックビューモデルを使用して、デザイン時のデータをビューに提供できます。

上記を最もよく満たす提案はどれですか?オプション(1)と言います。単体テストを記述して、リストの最後のアイテムが常に「センチネル」アイテムであることを確認できます。

「実際のfooまたは新しいfooセンチネルのロジックをビューモデルに組み込む」には、型指定されたDataTemplatesを使用するだけです。

于 2012-05-21T21:18:26.663 に答える
1

TabControlを再テンプレート化し、タブの右側に偽のタブまたはボタンを追加するだけの方が簡単な場合があります。

基本的な例:

<Window x:Class="ContextMenuSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <SolidColorBrush x:Key="WindowBackgroundBrush"
                         Color="#FFF" />

        <SolidColorBrush x:Key="SolidBorderBrush"
                         Color="#888" />

        <SolidColorBrush x:Key="DisabledForegroundBrush"
                         Color="#888" />

        <SolidColorBrush x:Key="DisabledBorderBrush"
                         Color="#AAA" />

        <Style  TargetType="{x:Type TabControl}">
            <Setter Property="OverridesDefaultStyle"
                    Value="True" />
            <Setter Property="SnapsToDevicePixels"
                    Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid KeyboardNavigation.TabNavigation="Local">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <TabPanel Name="HeaderPanel"
                                      Grid.Row="0"
                                      Panel.ZIndex="1"
                                      Margin="0,0,4,-1"
                                      IsItemsHost="True"
                                      KeyboardNavigation.TabIndex="1"
                                      Background="Transparent" />
                            <Button Grid.Row="0"
                                    Grid.Column="1"
                                    Content="Add new" />
                            <Border Name="Border"
                                    Grid.Row="1"
                                    Grid.ColumnSpan="2"
                                    Background="{StaticResource WindowBackgroundBrush}"
                                    BorderBrush="{StaticResource SolidBorderBrush}"
                                    BorderThickness="1"
                                    CornerRadius="2"
                                    KeyboardNavigation.TabNavigation="Local"
                                    KeyboardNavigation.DirectionalNavigation="Contained"
                                    KeyboardNavigation.TabIndex="2">
                                <ContentPresenter Name="PART_SelectedContentHost"
                                                  Margin="4"
                                                  ContentSource="SelectedContent" />
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled"
                                     Value="False">
                                <Setter Property="Foreground"
                                        Value="{StaticResource DisabledForegroundBrush}" />
                                <Setter TargetName="Border"
                                        Property="BorderBrush"
                                        Value="{StaticResource DisabledBorderBrush}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>

    <Grid>
        <TabControl>
            <TabItem Header="Item 1" />
            <TabItem Header="Item 2" />
        </TabControl>
    </Grid>

</Window>

enter code here
于 2012-05-23T11:31:05.293 に答える
0

私は最初のものを選びます:

TabViewsしたがって、すべてが最後の場合、アクティブ化されたときに新しいものを作成し、それ自体の前に注入する場所のコレクションがあります。

スタイリングについてはどうでしょうか。UIの一部にしたい場合は、後で行うこともできます。それがの強みですWPF

したがって、一般的に、ソリューションは、あなたが話していた両方のソリューションの一種のマージになります。TabView コレクションの最後のスタイルテンプレートを作成し、それをそれにのみ適用することを止めることはできません。

お役に立てれば。

于 2012-05-21T20:57:46.023 に答える