![](/img/trans.png)
[英]Calling a command in my ViewModel from a binding to an event in my XAML?
[英]Data from ViewModel is not binding to XAML from PageLoad Event
我是 MVVM 架構的新手。 我正在構建一個 UWP 應用程序。 我基本上有一個視圖(XAML)、代碼隱藏(Xaml.cs)、ViewModel 和數據服務。
我的視圖/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
當你設置不但是空DataContext
在Page_Loaded
將發生結合DataContext
為空,因此你看不到數據查看。
現在,如果可以的話,我會建議您在綁定之前在構造函數中初始化視圖模型。 但是,如果由於某種原因您需要將它綁定到Page_Loaded
事件中,您需要一種方法來告訴您視圖在更改時更新值。
幸運的是,框架已經為此提供了解決方案,您可以在 ViewModel 上使用INotifyPropertyChanged
接口,以便它可以通知視圖有關屬性值更改的信息,我猜是Value.ProgressPercentage
。
但是您必須編寫一個事件處理程序來相應地更新您的視圖
像這樣的東西
private void OnViewModelPropertyChange(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(ViewModel.prop1):
// do something
break;
case nameof(ViewModel.prop2):
// do something else
break;
}
}
這就是為什么我建議您改用數據綁定,這不是非常復雜,但它會為您節省幾行額外的編碼。
現在在后面的代碼中:
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)並將其保存在代碼隱藏類的屬性中,然后我使用該屬性設置了數據上下文。 后來我將 itemssource 與該對象的 UploadProgressInfoDict 綁定,例如
ItemsSource="{Binding VM.UploadProgressInfoDict}"
刪除了這件作品,它工作正常!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.