2017-07-08 43 views
1

我寫了一個簡單的應用程序在C#中使用Xamarin.Forms與Visual Studio 2017,並有一個數據綁定工作來更新內容的問題標籤子控件的顯示DatePicker子控件在同一個ContentPage中選定的日期值。儘管所有的項目元素編譯,構建和部署都沒有任何錯誤,並且每次在DatePicker中選擇日期時都會調用ViewModel中的OnPropertyChanged方法,但是當PropertyChanged事件處理程序中的PropertyChanged事件處理程序始終爲空對象引用時OnPropertyChanged方法被調用,並且不會按照預期的方式使用新的選定日期值更新Label的Text屬性的內容。Xamarin.Forms&MVVM在C#中:PropertyChanged事件處理程序總是空時OnPropertyChanged被稱爲

以下是我的MainPage實現,除了支持ViewModel類SelectedDateViewModel.cs。

C#[MainPage.xaml.cs中]

using System; 
using Xamarin.Forms; 

namespace DataBoundDatePicker 
{ 
    public partial class MainPage : ContentPage 
    { 
     public MainPage() 
     { 
      InitializeComponent(); 

      BindingContext = new SelectedDateViewModel(); 
     } 
    } 
} 

XAML [MainPage.xaml中]

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:DataBoundDatePicker" 
      x:Class="DataBoundDatePicker.MainPage"> 
    <StackLayout Padding="20" VerticalOptions="Center" HorizontalOptions="Center"> 
     <Label Text="Data Bound DatePicker" FontAttributes="Bold" HorizontalOptions="Center" /> 
     <Label Text="Select a Date:" /> 
     <DatePicker x:Name="SelectedDatePicker" Date="{Binding SelectedDate}"/> 
     <StackLayout Orientation="Horizontal"> 
      <Label Text="Formatted Date:" /> 
      <Label x:Name="FormattedDateLabel" Text="{Binding SelectedDate, StringFormat='{0:dddd, MMMM d, yyyy}'}" /> 
     </StackLayout> 
    </StackLayout> 
</ContentPage> 

C#[SelectedDateViewModel.cs]

using System; 
using System.ComponentModel; 
using System.Diagnostics; 

namespace DataBoundDatePicker 
{ 
    public class SelectedDateViewModel 
    { 
     private readonly string FullDateFormat = "dddd, MMMM d, yyyy"; 

     private DateTime selectedDate; 

     public event PropertyChangedEventHandler PropertyChanged; 

     public SelectedDateViewModel() 
     { 
      Debug.WriteLine("Entering SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 

      SelectedDate = DateTime.Now; 

      Debug.WriteLine("Leaving SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 
     } 

     public DateTime SelectedDate 
     { 
      get 
      { 
       return selectedDate; 
      } 

      set 
      { 
       if (selectedDate != value) 
       { 
        selectedDate = value; 
        OnPropertyChanged("SelectedDate"); 
       } 
      } 
     } 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      Debug.WriteLine("Inside SelectedDateViewModel.OnPropertyChanged()"); 

      Debug.WriteLine($"SelectedDate = {selectedDate.ToString(FullDateFormat)}"); 

      var trace = 
      $"PropertyChanged Is Null: {(PropertyChanged == null ? "Yes" : "No")}"; 
      Debug.WriteLine(trace); 

      var propertyChangedCallback = PropertyChanged; 
      propertyChangedCallback?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

當前實現執行以下操作:

  • 在啓動時,FormattedDateLabel顯示正確的格式基於 SelectedDateViewModel的SelectedDate的DateTime屬性 日期字符串。但是,對SelectedDatePicker控件中Date 屬性的任何後續更改。

  • 沒有失敗,每一次的日期值在 SelectedDatePicker控制改變時, SelectedDateViewModel.OnPropertyChanged()方法被調用總是, 甚至通過的MainPage的實例化和 SelectedDateViewModel對象實例啓動(如構造函數調用)。

  • 雖然SelectedDateViewModel.OnPropertyChanged()的日期值中的DatePicker改變時調用的任何 時間, SelectedDateViewModel的PropertyChanged事件的參考始終是 空,甚至在啓動時(同樣,當通過構造函數調用 實例化) 。這被示出具有發射作爲該程序的下面的調試跟蹤語句 在調試模式通過Visual Studio中 運行:

'DataBoundDatePicker.UWP.exe'(CoreCLR:CoreCLR_UWP_Domain):加載 「C :\工作\ Xamarin \ DataBoundDatePicker \ DataBoundDatePicker \ DataBoundDatePicker.UWP \ BIN \ 86 \調試\ AppX中\ Xamarin.Forms.Xaml.dll」。 跳過加載符號。模塊已經過優化,調試器選項 「Just My Code」已啓用。 輸入MainPage.MainPage() - 構造函數 輸入SelectedDateViewModel.SelectedDateViewModel() - 構造函數 Inside SelectedDateViewModel。OnPropertyChanged() SelectedDate =週二,2017年7月4日 的PropertyChanged爲空:是 離開SelectedDateViewModel.SelectedDateViewModel() - 構造 離開MainPage.MainPage() - 構造 線程0x1630已退出,代碼爲0(爲0x0)。 內SelectedDateViewModel.OnPropertyChanged() SelectedDate =星期日,2012年3月4日 的PropertyChanged爲空:是

  • 的代碼表現出相同的行爲,不管部署和調試 的UWP的或Android版應用。

任何幫助或洞察力和解釋,你可以在我怎樣才能得到Text屬性有其Text屬性綁定到使用視圖模型,其中PropertyChanged事件是不是空引用,將不勝感激的 日期財產份額。

預先感謝您的時間和幫助。

回答

3

使用INotifyPropertyChanged接口。喜歡這個。

public class SelectedDateViewModel : INotifyPropertyChanged 
    { 
     private readonly string FullDateFormat = "dddd, MMMM d, yyyy"; 

     private DateTime selectedDate; 

     public event PropertyChangedEventHandler PropertyChanged; 

     public SelectedDateViewModel() 
     { 
      Debug.WriteLine("Entering SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 

      SelectedDate = DateTime.Now; 

      Debug.WriteLine("Leaving SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 
     } 

     public DateTime SelectedDate 
     { 
      get 
      { 
       return selectedDate; 
      } 

      set 
      { 
       if (selectedDate != value) 
       { 
        selectedDate = value; 
        OnPropertyChanged("SelectedDate"); 
       } 
      } 
     } 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
        PropertyChanged(this, 
         new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
+0

Pratik; 謝謝你的回覆。我改變OnPropertyChanged()如你所說的落實,是的PropertyChanged仍然無效,即使在構造函數的調用: 內SelectedDateViewModel.OnPropertyChanged() SelectedDate =週四,2018年8月9日 的PropertyChanged爲空:是 – ClockEndGooner

+0

是你使用SelectedDateViewModel:INotifyPropertyChanged? – Pratik

+0

是的,Pratik,我重寫(複製/粘貼)OnPropertyChanged()的實現,並且PropertyChanged事件處理程序始終爲null。我爲這個麻煩道歉,但我錯過了別的什麼? – ClockEndGooner

相關問題