2015-04-28 56 views
2

这是我第一次使用C#以及.net的一般体验。我试图理解MVVM以及它如何与我想构建的屏幕一起工作。ViewModels PropertyChanged事件后的属性始终为空

当我点击不同的按钮后改变它时,我的按钮文本没有更新。调试器显示即使OnPropertyChanged函数被调用,PropertyChanged也始终为空。

我已经看过一些文档,并看过其他人的帖子提问类似的问题,但没有任何解决方案为我工作。我也在寻找一个解释,所以我可以理解我做错了什么。

代码:

MonthViewPage.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" 
      x:Class="Mobile_Release_POC_4.MonthViewPage" 
      xmlns:local="clr-namespace:Mobile_Release_POC_4;assembly=Mobile_Release_POC_4" 
      xmlns:telerikInput="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib"> 

      <ContentPage.BindingContext> 
       <local:WeekViewDatesViewModel MiddleWeekViewDate='{x:Static sys:DateTime.Now}' /> 
      </ContentPage.BindingContext> 

      <StackLayout> 
       <Label Text="Monday, April 27, 2015" 
       HorizontalOptions="Center"></Label> 

       <Grid Padding="0" ColumnSpacing="-2"> 

        <Grid.RowDefinitions> 
          <RowDefinition Height="75" /> 
        </Grid.RowDefinitions> 

        <Grid.ColumnDefinitions > 
          <ColumnDefinition Width="50" /> 
        </Grid.ColumnDefinitions> 

        <Button x:Name="monthViewDateButton1" 
          Text="{Binding MiddleWeekViewDate}" 
          FontSize="10" 
          Grid.Row="0" 
          Grid.Column="0" 
         /> 
        <Button x:Name="monthViewDateButton2" 
        Text="Tue 4/28" 
        FontSize="10" 
        Grid.Row="0" 
        Grid.Column="1" 
        Clicked="OnButtonClicked" 
        /> 

       </Grid> 


     </StackLayout> 

MonthViewPage.xaml.cs

using Xamarin.Forms; 

namespace Mobile_Release_POC_4 
{ 
public partial class MonthViewPage : ContentPage 
{ 
    public MonthViewPage() 
    { 
     InitializeComponent(); 

    } 


    void OnButtonClicked(object sender , EventArgs args){ 

     WeekViewDatesViewModel dc = new WeekViewDatesViewModel(); 

     dc.MiddleWeekViewDate = new DateTime (2014, 2, 2); 
    } 
} 

WeekViewDatesViewModel.cs

namespace Mobile_Release_POC_4 
{ 
    public class WeekViewDatesViewModel : INotifyPropertyChanged 
    { 
     DateTime middleWeekViewDate; 


     public event PropertyChangedEventHandler PropertyChanged; 


     public DateTime MiddleWeekViewDate 
     { 
      set 
      { 
       if (middleWeekViewDate != value) 
       { 
        middleWeekViewDate = value; 
        OnPropertyChanged("MiddleWeekViewDate"); 
       } 
      } 
      get 
      { 
       return middleWeekViewDate; 
      } 
     } 

     protected void OnPropertyChanged(string propertyName) 
     { 
      var handler = PropertyChanged; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, 
        new PropertyChangedEventArgs(propertyName)); 
      } 
     } 


    } 
} 

谢谢

+0

你按一下按钮创建一个新的视图模型*每次*,设定值,然后将它扔了出去。当然,这不会影响您实际用作数据上下文的完全其他视图模型。您应该更新该视图模型。并使用命令在viewmodel *本身上执行数据更改*。 – poke

+0

好吧,这是有道理的,而且这是我的重大监督。因此,如何改变viewModel本身?我见过的一些例子涉及使用DataContext,但目前我似乎无法访问它。 – Kyle

+1

这就是为什么我说使用命令;您将按钮命令绑定到视图模型,因此方法会在视图模型实例本身上执行。因此,您可以在同一个内部执行视图模型的实例。搜索'RelayCommand'或'DelegateCommand'。 – poke

回答

0

只有创建一个视图模型,其范围是页面的生命(至少)。

你的代码改成这样:

public partial class MonthViewPage : ContentPage 
{ 

    public WeekViewDatesViewModel VM { get; set; } 

    public MonthViewPage() 
    { 
     DataContext = VM = new WeekViewDatesViewModel(); 
     InitializeComponent(); 
    } 


    void OnButtonClicked(object sender , EventArgs args){ 

     VM.MiddleWeekViewDate = new DateTime (2014, 2, 2); 
    } 
} 
+0

谢谢你的帖子。它告诉我DataContext在当前上下文中不存在。我在其他地方看到了这个例子,但是我没有能力引用DataContext? – Kyle

+0

所以它看起来像自从我做一个Xamarin.forms实现也许我应该使用BindingContext而不是DataContext? – Kyle

+0

@凯尔我已经完成了Windows手机,但没有与Xamarin。数据上下文的概念(在xaml(WPF/Silverlight/WP)中是每一个控件和页面都有一个上下文,如果没有指定上下文,那么它继承父页面上下文一直到页面。只是将页面的上下文设置为ViewModel,最终在上述场景中将由控件访问。 – OmegaMan