这是我的情况。我有一个页面可以从数据库中加载碱基列表。如果导航到页面,则调用构造函数,并调用我的LoadBases()函数。太好了,正是我所需要的。
问题:
如果我离开该页面并从另一个页面向数据库中添加更多基础,然后又向后导航,则不会调用构造函数,因此新的基础不会加载到我的基础列表中。
我尝试过的事情:
在MVVMLight中查看模型定位器
public class ViewModelLocator
{
static ViewModelLocator()
{
SetupNavigation();
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<BomConfiguratorContext>();
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IUnitOfWork, UnitOfWork>();
}
else
{
SimpleIoc.Default.Register<IUnitOfWork, UnitOfWork>();
}
// SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<LoginViewModel>();
SimpleIoc.Default.Register<UserNavigationViewModel>();
SimpleIoc.Default.Register<AddNewBasesViewModel>();
SimpleIoc.Default.Register<AddNewBillOfMaterialsViewModel>();
SimpleIoc.Default.Register<AddNewOptionsViewModel>();
SimpleIoc.Default.Register<AddNewRulesViewModel>();
SimpleIoc.Default.Register<GenerateBillOfMaterialsViewModel>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public LoginViewModel LoginViewModel
{
get{ return ServiceLocator.Current.GetInstance<LoginViewModel>(); }
}
public UserNavigationViewModel ManageRulesViewModel
{
get { return ServiceLocator.Current.GetInstance<UserNavigationViewModel>(); }
}
public AddNewBasesViewModel AddNewBasesViewModel
{
get { return ServiceLocator.Current.GetInstance<AddNewBasesViewModel>(); }
}
public AddNewBillOfMaterialsViewModel AddNewBillOfMaterialsViewModel
{
get { return ServiceLocator.Current.GetInstance<AddNewBillOfMaterialsViewModel>(); }
}
public AddNewOptionsViewModel AddNewOptionsViewModel
{
get { return ServiceLocator.Current.GetInstance<AddNewOptionsViewModel>(); }
}
public AddNewRulesViewModel AddNewRulesViewModel
{
get
{
SimpleIoc.Default.Unregister<AddNewRulesViewModel>();
SimpleIoc.Default.Register<AddNewRulesViewModel>();
return ServiceLocator.Current.GetInstance<AddNewRulesViewModel>();
}
}
public GenerateBillOfMaterialsViewModel GenerateBillOfMaterialsViewModel
{
get{return ServiceLocator.Current.GetInstance<GenerateBillOfMaterialsViewModel>();}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{
}
private static void SetupNavigation()
{
SimpleIoc.Default.Unregister<INavigationService>();
var navigationService = new FrameNavigationService();
navigationService.Configure("LoginView", new Uri("/Views/LoginView.xaml", UriKind.Relative));
navigationService.Configure("UserNavigationView", new Uri("/Views/UserNavigationView.xaml", UriKind.Relative));
navigationService.Configure("AddNewBasesView", new Uri("/Views/Bases/AddNewBasesView.xaml", UriKind.Relative));
navigationService.Configure("AddNewBillOfMaterialsView", new Uri("/Views/BillOfMaterials/AddNewBillOfMaterialsView.xaml", UriKind.Relative));
navigationService.Configure("AddNewOptionsView", new Uri("/Views/Options/AddNewOptionsView.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep1", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep1.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep2", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep2.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep3", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep3.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep4", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep4.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep5", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep5.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep6", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep6.xaml", UriKind.Relative));
navigationService.Configure("AddNewRulesViewStep7", new Uri("/Views/Rules/AddNewRules/AddNewRulesStep7.xaml", UriKind.Relative));
navigationService.Configure("GenerateBillOfMaterialsView", new Uri("/Views/BillOfMaterials/GenerateBillOfMaterialsView.xaml", UriKind.Relative));
SimpleIoc.Default.Register<INavigationService>(() => navigationService);
}
}
查看采用INavigationService的模型
仅是我如何注入导航服务并将其用于导航页面的示例。
public LoginViewModel(IUnitOfWork unitOfWork, INavigationService navService)
{
_UnitOfWork = unitOfWork;
_NavigationService = navService;
LoginCommand = new RelayCommand<IHavePassword>((IHavePassword parameter) => LoginAsync(parameter));
}
导航到页面
private async void LoginAsync(IHavePassword parameter)
{
if( await Task<bool>.Run(() => Login(parameter)))
_NavigationService.NavigateTo("UserNavigationView");
}
我正在导航到的页面
这只是我如何在页面中使用数据上下文的一个示例。
<local:BasePage x:Class="YAI.BomConfigurator.Desktop.Views.UserNavigationView"
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"
xmlns:local="clr-namespace:YAI.BomConfigurator.Desktop"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800"
Title="UserNavigationView"
DataContext="{Binding ManageRulesViewModel, Source={StaticResource Locator}}">
<Border>
<Grid>
<ScrollViewer>
<StackPanel
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextBlock.TextAlignment="Center">
<Border Background="{StaticResource BackgroundLightBrush}"
CornerRadius="10"
Padding="15 50 15 15"
Width="600"
Margin="50 50 50 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.ColumnSpan="2" Text="I Would Like To..."
FontSize="{StaticResource FontSizeLarge}"
FontFamily="{StaticResource LatoRegular}"
Foreground="{StaticResource MediumBlueBrush}"
Margin="0 0 0 15"/>
<StackPanel Grid.Column="0" Margin="0 0 25 0">
<Button Content="Generate BOMs"
Margin="0 50 0 20"
Command="{Binding GenerateBillOfMaterialsCommand}"/>
<Button Content="Check Rules"
Margin="0 25 0 20"
Command="{Binding CheckRulesCommand}"/>
<Button Content="Add New Options"
Margin="0 25 0 20"
Command="{Binding AddNewOptionsCommand}"/>
</StackPanel>
<StackPanel Grid.Column="1">
<Button Content="Add New BOMs"
Margin="0 50 0 20"
Command="{Binding AddNewBillOfMaterialsCommand}" />
<Button Content="Add New Rules"
Margin="0 25 0 20"
Command="{Binding AddNewRulesCommand}"/>
<Button Content="Add New Bases"
Margin="0 25 0 20"
Command="{Binding AddNewBasesCommand}"/>
</StackPanel>
</Grid>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
此解决方案的问题在于,在每次调用视图模型时注销和重新注册视图模型时,当我浏览所有都使用datacontext AddNewRulesViewModel的视图时,它将从字面上清除所有变量并为每个对象调用构造函数页面(其中有7个使用相同的视图模型)。
所以我要寻找的是仅当我导航到特定页面时才调用LoadBases()函数的方法。谁能给我一些有关如何解决此问题的建议?
答案 0 :(得分:1)
我最终解决此问题的方法是在页面加载事件上使用事件触发器。这是我所做的小事。
以xaml触发
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadAllDataCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
查看模型LoadAllDataCommand
LoadAllDataCommand = new RelayCommand(async () => await LoadAllDataAsync());
查看模型命令操作
private async Task LoadAllDataAsync()
{
AllBases.Clear();
try
{
using (var UOW = _UnitOfWorkFactory.Create())
{
foreach (Base ba in await Task.Run(() => _BaseRepository.GetAll()))
{
AllBases.Add(ba);
}
}
}
catch (Exception)
{
await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => {
Messenger.Default.Send(new ToastErrorMessage { Message = "Error: There was a problem with loading the data" });
}));
}
}
因此,每次加载页面时,都会使用所有新添加的库从数据库中重新加载我的数据。