0

我有一个主视图和两个子视图。单击 SubViewA 上的按钮时,我想从 SubViewA 切换到 SubViewB。masterview 包含一个绑定到 View 的 contentpresenter,并在加载时初始化为 SubViewB。单击 SubViewA 上的按钮时,将调用 SubViewB 构造函数,但从未加载控件。我错过了什么?我也尝试过设置内容模板:

<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();
    }      
}

子视图A:

<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();
    }
}

视图模型:

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

View-models 不应该包含对视图的引用,而是有一个属性ViewMode可以是一个enum并触发它,这里是一个例子(你也可以设置ContentTemplate而不是Content)。

于 2012-08-15T16:29:21.177 回答
0

好的,对我有用的解决方案是:

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 回答