簡體   English   中英

來自 ViewModel 的數據未從 PageLoad 事件綁定到 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>());

        }

如何解決這個問題?

所以代碼將執行的順序是

  1. 構造函數調用
  2. 查看元素創建
  3. 捆綁
  4. 頁面加載事件(僅在添加所有子項時發生)

正在發生的事情有,當你設置你DataContext在構造函數中結合進來的時候DataContext當你設置不但是空DataContextPage_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM