【问题标题】:ViewModels Property after PropertyChanged event is always NullPropertyChanged 事件后的 ViewModels 属性始终为 Null
【发布时间】:2015-07-07 11:54:15
【问题描述】:

这是我对 C# 以及 .net 的第一次体验。我试图了解 MVVM 以及它如何与我想要构建的屏幕一起工作。

当我在单击不同按钮后更改按钮文本时,它没有更新。调试器显示,即使调用 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));
            }
        }


    }
}

谢谢

【问题讨论】:

  • 您的按钮单击每次都会创建一个新的视图模型,设置值,然后将其丢弃。当然,这不会影响您实际用作数据上下文的完全其他视图模型。您应该更新该视图模型。并使用命令在 viewmodel 本身上执行数据更改。
  • 好的,是的,这是有道理的,是的,这是我的一个重大疏忽。那么,我该如何改变 viewModel 本身呢?我见过的一些示例涉及使用 DataContext,但我目前似乎无法访问它。
  • 这就是我说使用命令的原因;您将按钮命令绑定到视图模型,因此在视图模型实例本身上执行了一个方法。因此,当您在同一视图模型中执行时,您将拥有视图模型的实例。搜索RelayCommandDelegateCommand
  • 使用 Snoop 在运行时检查您的绑定。

标签: c# .net mvvm xamarin


【解决方案1】:

只创建一个ViewModel,它的范围是页面的生命(至少)。

将您的代码更改为:

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);
    }
}

【讨论】:

  • 感谢您的帖子。它告诉我 DataContext 在当前上下文中不存在。我在其他地方看到了这个例子,但我没有能力引用 DataContext?
  • 所以看起来我正在执行 Xamarin.forms 实现,也许我应该使用 BindingContext 而不是 DataContext?
  • @Kyle 我已经完成了 windows phone,但没有使用 Xamarin。数据上下文的概念(在 xaml (WPF/Silverlight/WP) 中是每个控件连同页面都有一个上下文。如果没有指定上下文,那么它会一直继承父级的上下文直到页面。我只是将页面的上下文设置为 ViewModel,最终将在上述场景中由控件访问。
猜你喜欢
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
  • 1970-01-01
相关资源
最近更新 更多