Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF将相同的DataContex分配给多个页面MVVM_Wpf_Mvvm_Datacontext - Fatal编程技术网

WPF将相同的DataContex分配给多个页面MVVM

WPF将相同的DataContex分配给多个页面MVVM,wpf,mvvm,datacontext,Wpf,Mvvm,Datacontext,我有一个有多个框架的窗口。每个框架包含一个或多个页面。所有页面都使用相同的ViewModel。我控制每个框架的可见性以操纵UI 我最近意识到,当我的程序启动时,每个页面都会触发ViewModel的同一个构造函数(因此同一个构造函数会触发多次)(构造函数中的一个简单MessageBox.Show会在启动时触发多次)。这对我来说是有道理的,但不是我想要的 此外,我开始相信,我在C#中操纵不同帧时遇到问题的原因是我可能创建了ViewModel的新“对象”??我不确定这是不是真的发生了,但我很确定这不是

我有一个有多个框架的窗口。每个框架包含一个或多个页面。所有页面都使用相同的ViewModel。我控制每个框架的可见性以操纵UI

我最近意识到,当我的程序启动时,每个页面都会触发ViewModel的同一个构造函数(因此同一个构造函数会触发多次)(构造函数中的一个简单MessageBox.Show会在启动时触发多次)。这对我来说是有道理的,但不是我想要的

此外,我开始相信,我在C#中操纵不同帧时遇到问题的原因是我可能创建了ViewModel的新“对象”??我不确定这是不是真的发生了,但我很确定这不是我想要的

是否有一种方法可以为页面设置DataContext(在Xaml中),以便构造函数只触发一次,但仍然将每个页面的DataContext设置为ViewModel?还是我应该探索一种不同的方法?我还在学习

每个页面都有以下Xaml:

<Page.DataContext>
    <ViewModel:ActiveJobViewModel/>
</Page.DataContext>

我的镜框看起来像这样。我意识到一个框架可以容纳多个页面,但是操纵可视性给了我更好的性能,我不希望每次页面源更改时都运行构造函数

<Frame Source="ActiveJobPage.xaml" Grid.Row="2" Grid.Column="3" 
       Visibility="{Binding ElementName=ActiveJobPageToggleButton, Path=IsChecked, Converter={StaticResource booleanToVisibility}, UpdateSourceTrigger=PropertyChanged}" 
       Style="{StaticResource FramePage}">
</Frame>

<Frame  Source="CustomerPage.xaml" Grid.Row="2" Grid.Column="3"
        Visibility="{Binding objHomePage_PageVisibility.CustomersPageToggleButtonIsChecked, Converter={StaticResource booleanToVisibility}, UpdateSourceTrigger=PropertyChanged}"
        Style="{StaticResource FramePage}">
</Frame>

从XAML页删除以下内容

<Page.DataContext>
    <ViewModel:ActiveJobViewModel/>
</Page.DataContext>

然后创建ActiveJobViewModel实例的公共实例,并为多个页面设置相同的datacontext。

以下操作将创建
ActiveJobViewModel
类的新实例:

<ViewModel:ActiveJobViewModel/>
XAML:

<Frame Source="ActiveJobPage.xaml" Grid.Row="2" Grid.Column="3"
        LoadCompleted="Frame_LoadCompleted"
        Visibility="{Binding ElementName=ActiveJobPageToggleButton, Path=IsChecked, Converter={StaticResource booleanToVisibility}, UpdateSourceTrigger=PropertyChanged}" 
        Style="{StaticResource FramePage}">
</Frame>


不要忘记从页面中删除
元素。

谢谢。您能解释一下“手动将两个页面的DataContext设置为代码中的同一实例”是什么意思吗?请参阅更新的答案。这有意义吗?您必须创建一个公共DataContext实例,并专门为多个页面进行设置。。。我删除了Xaml数据上下文。我将SetDataContext方法添加到我的每个页面中,如果这是您想要我做的。但是,我不确定应该在何处/如何创建ActiveJobViewModel的公共实例,或者如何为多个页面设置相同的DataContext?抱歉,我有点纠结于此……在研究过程中,我找到了这个基于Xaml的答案。C#或Xaml对我来说并不重要。我只是想了解。。。我相信它也在完成同样的事情。CharithJ你同意吗?@mjordan:很抱歉,我没有听到你的评论。是的,那也一样。如果DataContext在运行时可以更改,我认为您需要DynamicSource。这也是一个很好的方法。最终,我在App.xaml中定义了ViewModel,然后在xaml中应用了页面的dataContext。DataContext=“{StaticResource ActiveJobViewModel}”。到目前为止,这似乎是工作的方式,我希望。谢谢你的回复。我不断地向他们学习!
<Window ...>
    <Window.Resources>
        <ViewModel:ActiveJobViewModel x:Key="viewModel"/>
    </Window.Resources>
    <!-- frames ... -->
</Window>
private void Frame_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
    Frame frame = (Frame)sender;
    FrameworkElement content = frame.Content as FrameworkElement;
    if (content != null)
        content.DataContext = Resources["viewModel"];
}
<Frame Source="ActiveJobPage.xaml" Grid.Row="2" Grid.Column="3"
        LoadCompleted="Frame_LoadCompleted"
        Visibility="{Binding ElementName=ActiveJobPageToggleButton, Path=IsChecked, Converter={StaticResource booleanToVisibility}, UpdateSourceTrigger=PropertyChanged}" 
        Style="{StaticResource FramePage}">
</Frame>