WPF 将相同的 DataContex 分配给多个页面 MVVM
WPF Assigning the Same DataContex to Multiple Pages MVVM
我有一个 Window 有多个框架。每个框架包含一个或多个页面。所有页面都使用相同的 ViewModel。我控制每个Frame的Visibility来操纵UI.
我最近意识到,当我的程序启动时,每个页面都会触发 ViewModel 的同一个构造函数(因此同一个构造函数会触发多次)(构造函数中的一个简单 MessageBox.Show 会触发多个发射时间)。我能理解为什么会这样,但不是我想要的。
此外,我开始相信我在 C# 中操作不同框架时遇到问题的原因是因为我可能创建了新的 "objects" 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>
并在代码中手动将两个页面的DataContext设置为同一个实例。
例如在您的页面代码隐藏 class.
public void SetDataContext(ActiveJobViewModel commonContext)
{
this.DataContext = commonContext;
}
然后创建一个ActiveJobViewModel实例的公共实例,并为多个页面设置相同的datacontext。
以下创建 ActiveJobViewModel
class 的新实例:
<ViewModel:ActiveJobViewModel/>
如果您的所有页面和框架共享相同的视图模型,您只想执行一次 - 在定义框架的 window 中。如果将视图模型定义为 window:
中的资源
<Window ...>
<Window.Resources>
<ViewModel:ActiveJobViewModel x:Key="viewModel"/>
</Window.Resources>
<!-- frames ... -->
</Window>
...然后您可以处理 Frames
的 LoadCompleted
事件并以编程方式设置其内容的 DataContext
:
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"];
}
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>
不要忘记从页面中删除 <Page.DataContext>
元素。
我有一个 Window 有多个框架。每个框架包含一个或多个页面。所有页面都使用相同的 ViewModel。我控制每个Frame的Visibility来操纵UI.
我最近意识到,当我的程序启动时,每个页面都会触发 ViewModel 的同一个构造函数(因此同一个构造函数会触发多次)(构造函数中的一个简单 MessageBox.Show 会触发多个发射时间)。我能理解为什么会这样,但不是我想要的。
此外,我开始相信我在 C# 中操作不同框架时遇到问题的原因是因为我可能创建了新的 "objects" 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>
并在代码中手动将两个页面的DataContext设置为同一个实例。
例如在您的页面代码隐藏 class.
public void SetDataContext(ActiveJobViewModel commonContext)
{
this.DataContext = commonContext;
}
然后创建一个ActiveJobViewModel实例的公共实例,并为多个页面设置相同的datacontext。
以下创建 ActiveJobViewModel
class 的新实例:
<ViewModel:ActiveJobViewModel/>
如果您的所有页面和框架共享相同的视图模型,您只想执行一次 - 在定义框架的 window 中。如果将视图模型定义为 window:
中的资源<Window ...>
<Window.Resources>
<ViewModel:ActiveJobViewModel x:Key="viewModel"/>
</Window.Resources>
<!-- frames ... -->
</Window>
...然后您可以处理 Frames
的 LoadCompleted
事件并以编程方式设置其内容的 DataContext
:
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"];
}
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>
不要忘记从页面中删除 <Page.DataContext>
元素。