更新绑定对象时,ContentPresenter的绑定未更新

时间:2012-08-15 16:22:41

标签: wpf user-controls

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

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

也不起作用。

MainWindow:

<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
{
}

提前致谢。

3 个答案:

答案 0 :(得分:1)

视图模型不应包含对视图的引用,而是具有属性ViewMode,可以是enum并触发here is an example(您可以设置{{1}也可以代替ContentTemplate

答案 1 :(得分: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>

在viewmodel中:

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
{
}

答案 2 :(得分: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上设置View,而是在子视图上设置(从MainViewModel继承)。删除继承以实际设置MainViewModel上的视图一切正常。