如何解决ViewModel中的数据未从PageLoad事件
我是MVVM架构的新手。我正在构建一个UWP应用。我基本上有一个View(XAML),后面的代码(Xaml.cs),ViewModel和数据服务。
我的View / XAML看起来像这样:
<Page
x:Class="SnapBilling.SyncModule.SyncView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d" Loaded="Page_Loaded"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.Resources>
<!--DataTemplate for Published Date column defined in Grid.Resources. PublishDate is a property on the ItemsSource of type DateTime -->
<DataTemplate x:Key="ProgressTemplate" >
<ProgressBar x:Name="progressBar1" Value="{Binding Value.ProgressPercentage}" Maximum="100" Margin="20"/>
</DataTemplate>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="4*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<controls:DataGrid x:Name="BackupSummaryDataGrid"
Grid.Row="0"
Margin="40"
ItemsSource="{x:Bind DataContext.UploadProgressInfoDict}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AlternatingRowBackground="Transparent"
AreRowDetailsFrozen="False"
AreRowGroupHeadersFrozen="True"
AutoGenerateColumns="False"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
ColumnHeaderHeight="32"
FrozenColumnCount="0"
GridLinesVisibility="None"
HeadersVisibility="Column"
HorizontalScrollBarVisibility="Visible"
IsReadOnly="False"
MaxColumnWidth="400"
RowDetailsVisibilityMode="Collapsed"
RowGroupHeaderPropertyNameAlternative="Range"
SelectionMode="Extended"
VerticalScrollBarVisibility="Visible"
>
<controls:DataGrid.Columns>
<controls:DataGridTextColumn Tag="SyncType" Header="Sync Type" Binding="{Binding Key}" IsReadOnly="True" />
<controls:DataGridTextColumn Tag="remaining" Header="Pending Items" Binding="{Binding Value.remainingNow}" IsReadOnly="True" />
<controls:DataGridTemplateColumn Header="% remaining" CellTemplate="{StaticResource ProgressTemplate}" />
<controls:DataGridTextColumn Header="Status" Binding="{Binding Value.ProgressMessage}" IsReadOnly="True"/>
</controls:DataGrid.Columns>
</controls:DataGrid>
</Grid>
</Page>
现在,当页面/视图xaml加载时,它将调用xaml类的构造函数,在此我们初始化组件并使用视图模型对象设置数据上下文。这是类的代码,
public sealed partial class SyncView : Page,IView
{
public SyncView()
{
this.InitializeComponent();
DataContext = new SyncViewModel(ServiceLocator.Current.GetService<ICommonServices>());
}
private void Page_Loaded(object sender,RoutedEventArgs e)
{
}
}
现在,DataContext = new SyncViewModel(ServiceLocator.Current.GetService<ICommonServices>());
在这里创建了一个ViewModel对象,并将其正确绑定到数据上下文。
问题
当我通过Page_Loaded
事件而不是像下面的构造函数那样设置数据上下文时,viewmodel对象未绑定到页面的数据上下文。
private void Page_Loaded(object sender,RoutedEventArgs e)
{
DataContext = new SyncViewModel(ServiceLocator.Current.GetService<ICommonServices>());
}
如何解决这个问题?
解决方法
所以代码执行的顺序是
- 构造函数调用
- 查看元素创建
- 绑定
- 页面加载事件(仅在添加了所有子项时发生)
正在发生的事情是,当在绑定中出现DataContext
时在构造函数中设置DataContext
时不为空,但是在{{1}中设置DataContext
时}绑定将在Page_Loaded
为null的情况下发生,因此您在视图中看不到任何数据。
现在,如果可以的话,我建议您在绑定之前在构造函数中初始化View-model。但是,如果由于某种原因需要它绑定到DataContext
事件中,则需要一种方法来告诉您视图在值更改时进行更新。
幸运的是,该框架已经有解决方案,您可以在ViewModel上使用Page_Loaded
接口,以便可以通知视图有关属性值的更改,我猜想是INotifyPropertyChanged
。
但是您将必须编写一个事件处理程序,该事件处理程序将相应地更新您的视图
像这样的东西
Value.ProgressPercentage
这就是为什么我建议您改为使用数据绑定,这不是很复杂,但是它将为您节省几行额外的编码。
,现在在后面的代码中:
public SyncView()
{
this.Loaded += SyncView_Loaded;
}
private void SyncView_Loaded(object sender,RoutedEventArgs e)
{
this.InitializeComponent();
DataContext = new SyncViewModel(ServiceLocator.Current.GetService<ICommonServices>());
}
在XAML中:
ItemsSource="{Binding UploadProgressInfoDict}"
原因:之前我创建了一个视图模型对象(例如VM),并将其保存在codebehind类的属性中,然后我使用该属性设置了datacontext。后来我将itemsource与该对象的UploadProgressInfoDict绑定在一起,例如
ItemsSource="{Binding VM.UploadProgressInfoDict}"
删除了这部分,效果很好!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。