0

マスタービューと2つのサブビューがあります。SubViewAのボタンをクリックすると、SubViewAからSubViewBに切り替えたいのですが。マスタービューには、ビューにバインドされ、ロード時にSubViewBに初期化されるコンテンツプレゼンターが含まれています。SubViewAのボタンをクリックすると、SubViewBコンストラクターが呼び出されますが、コントロールがロードされることはありません。私は何が欠けていますか?また、contenttemplateを設定するだけで試してみました。

<ContentPresenter x:Name="contentPresenter" Content="{Binding View, PresentationTraceSources.TraceLevel=High}" />

これも機能しません。

メインウィンドウ:

<Window x:Class="WpfApplication2.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"
    xmlns:local="clr-namespace:WpfApplication2">

<Grid>

    <TextBlock Text="MasterViewPage" />

    <ContentControl x:Name="content" Content="{Binding View}">
        <ContentControl.Resources>
            <DataTemplate DataType="{x:Type local:SubViewModelA}">
                <local:SubViewA></local:SubViewA>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:SubViewModelB}">
                <local:SubViewB></local:SubViewB>
            </DataTemplate>
        </ContentControl.Resources>
    </ContentControl>

</Grid>
</Window>

public partial class MainWindow
{
    public MainWindow()
    {
        Loaded += MainWindow_Loaded;
        InitializeComponent();
    }

    private void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        DataContext = new MainViewModel();
    }      
}

SubViewA:

<UserControl x:Class="WpfApplication2.SubViewA"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<Grid Margin="0,40,0,0">
    <TextBlock Text="Subview A" />

    <Button Height="50" Width="120" Content="Open View B" Command="{Binding OpenViewCommand}" />
</Grid>
</UserControl>

public partial class SubViewA
{
    public SubViewA()
    {
        Loaded += SubViewA_Loaded;
        InitializeComponent();
    }

    private void SubViewA_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        DataContext = new SubViewModelA();
    }
}

ViewModels:

public class MainViewModel : NotifyPropertyChanged
{
    private object _view;

    public object View
    {
        get { return _view; }
        set
        {
            _view = value;
            RaisePropertyChanged(() => View);
        }
    }

    public MainViewModel()
    {
        View = new SubViewA();
    }
}

public class SubViewModelA : MainViewModel
{
    public ICommand OpenViewCommand
    {
        get { return new DelegatingCommand(OpenView); }
    }

    private void OpenView()
    {
        View = new SubViewB();
    }
}

public class SubViewModelB : MainViewModel
{
}

前もって感謝します。

4

3 に答える 3

1

ビューモデルには、ビューへの参照を含めるべきではありません。代わりに、そのプロパティをトリガーするViewModeことができます。ここに例を示します(代わりにを設定することもできます)。enumContentTemplateContent

于 2012-08-15T16:29:21.177 に答える
0

OK、私のために働いた解決策は:

MainView.xaml:

    <ContentControl x:Name="content">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding View, PresentationTraceSources.TraceLevel=High}" Value="SubViewA">
                            <Setter Property="ContentTemplate">
                            <Setter.Value>
                                    <DataTemplate>
                                        <local:SubViewA />
                                    </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding View, PresentationTraceSources.TraceLevel=High}" Value="SubViewB">
                            <Setter Property="ContentTemplate">
                            <Setter.Value>
                                    <DataTemplate>
                                        <local:SubViewB />
                                    </DataTemplate>
                                </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>

およびSubViewA.xaml内:

<Button Height="50" Width="120" Content="Open View B" Command="{Binding Path=DataContext.OpenViewCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}, PresentationTraceSources.TraceLevel=High}" />

その理由は、ビューがMainViewModelではなく、サブビュー(MainViewModelから継承)に設定されていたためです。継承を削除して実際にMainViewModelにビューを設定すると、すべてが機能しました。

于 2012-08-16T11:50:53.550 に答える
0

モデルにビューを直接設定するのは良くないことに同意できます。しかしとにかく、私はあなたの解決策(両方)を試しましたが、SubViewBはまだロードされていません。コンストラクターが呼び出されますが、呼び出されることはありませんSubViewB_Loaded。したがって、結果として、SubViewBは表示されません。

datacontextchangedでトリガーされることはありませんcontentcontrol。それで、それでも、私は何かが欠けています。

メインビュー:

<Window x:Class="WpfApplication2.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"
    xmlns:local="clr-namespace:WpfApplication2">

<Grid>

    <TextBlock Text="MasterViewPage" />

    <ContentControl x:Name="content">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding View}" Value="SubViewA">
                        <Setter Property="Content">
                            <Setter.Value>
                                <local:SubViewA />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding View}" Value="SubViewB">
                        <Setter Property="Content">
                            <Setter.Value>
                                <local:SubViewB />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</Grid>
</Window>

そして、ビューモデルでは:

public class MainViewModel : NotifyPropertyChanged
{
    private string _view;

    public string View
    {
        get { return _view; }
        set
        {
            _view = value;
            RaisePropertyChanged(() => View);
        }
    }

    public MainViewModel()
    {
        View = "SubViewA";
    }
}

public class SubViewModelA : MainViewModel
{
    public ICommand OpenViewCommand { get { return new DelegatingCommand(OpenView); } }

    private void OpenView()
    {
        View = "SubViewB";
    }
}

public class SubViewModelB : MainViewModel
{
}
于 2012-08-16T08:16:39.780 に答える