2017-04-15 50 views
0

我希望这里的任何人都可以帮助我动态绑定数据。当我在一个按钮上添加一个列表项时,它不会在我的页面中更新,这也适用于向int添加一个值。然而,当我输入一个文本框时int会改变......所以我不明白发生了什么问题。我也不知道这是否正确。windows store动态数据绑定列表和其他类型

所以我qeustions的快速概览:

  1. 为什么这个不行?
  2. 这是正确的方法吗?
  3. 有人可以告诉我如何使它工作?

假定的错误位置:MainViewModel类中的NotifyPropertyChanged方法。 这是我项目中的所有代码,只是说它在另一个地方出错了,而不是我想象的那样。

我的XAML页面:

<Page 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:databinding_unittest0" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:ViewModels="using:databinding_unittest0.ViewModels" 
x:Class="databinding_unittest0.MainPage" 
mc:Ignorable="d"> 

<Page.DataContext> 
    <ViewModels:MainViewModel/> 
</Page.DataContext> 

<Grid> 
    <TextBox Text="{Binding Testvar, Mode=TwoWay}" Height="100" Margin="110,10,1023,658"/> 
    <TextBlock Text="{Binding Testvar}" Height="100" Margin="110,115,1023,553"/> 
    <ListBox ItemsSource="{Binding Persons}" Height="500" VerticalAlignment="Bottom"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <ListBoxItem Content="{Binding Fullname}"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Content="Add 1" HorizontalAlignment="Left" Margin="441,46,0,0" VerticalAlignment="Top" Click="Add1_Click"/> 
    <Button Content="Add list item" HorizontalAlignment="Left" Margin="609,46,0,0" VerticalAlignment="Top" Click="AddListItem_Click"/> 
</Grid> 
</Page> 

C#中的页面:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Windows.Foundation; 
using Windows.Foundation.Collections; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Controls.Primitives; 
using Windows.UI.Xaml.Data; 
using Windows.UI.Xaml.Input; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Navigation; 

using databinding_unittest0.ViewModels; 
using databinding_unittest0.Models; 

// The Blank Page item template is documented at 
// http://go.microsoft.com/fwlink/?LinkId=234238 

namespace databinding_unittest0 
{ 

    /// <summary> 
    /// An empty page that can be used on its own or navigated to within a Frame. 
    /// </summary> 
    public sealed partial class MainPage : Page 
    { 
     public MainViewModel mvm { get; set; } 
     public MainPage() 
     { 
      this.InitializeComponent(); 
      mvm = new MainViewModel(); 
     } 

     /// <summary> 
     /// Invoked when this page is about to be displayed in a Frame. 
     /// </summary> 
     /// <param name="e">Event data that describes how this page was reached. The Parameter 
     /// property is typically used to configure the page.</param> 
     protected override void OnNavigatedTo(NavigationEventArgs e) 
     { 
     } 

     private void Add1_Click(object sender, RoutedEventArgs e) 
     { 
      mvm.Testvar = mvm.Testvar + 1; 
     } 

     private void AddListItem_Click(object sender, RoutedEventArgs e) 
     { 
      mvm.Persons.Add(new Person() { Firstname="Kurt", Lastname="Cobain"}); 
     } 
    } 
} 

MainViewModel C#:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using Windows.ApplicationModel; 

using databinding_unittest0.Models; 


namespace databinding_unittest0.ViewModels 
{ 
    public class MainViewModel : INotifyPropertyChanged 
    { 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

     private List<Person> persons; 

     public List<Person> Persons 
     { 
      get { return persons; } 
      set 
      { 
       persons = value; 
       NotifyPropertyChanged(); 
      } 
     } 

     private int testvar; 

     public int Testvar 
     { 
      get { return testvar; } 
      set 
      { 
       testvar = value; 
       NotifyPropertyChanged(); 
      } 
     } 

     public MainViewModel() 
     { 
      Persons = new List<Person>(); 
      Persons.Add(new Person() { Firstname = "Henk", Lastname = "Jansen" }); 
     } 


     // This method is called by the Set accessor of each property. 
     // The CallerMemberName attribute that is applied to the optional propertyName 
     // parameter causes the property name of the caller to be substituted as an argument. 
     private void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      if (propertyName != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

人物C#:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace databinding_unittest0.Models 
{ 
    public class Person 
    { 
     public string Firstname { get; set; } 
     public string Lastname { get; set; } 
     public string Fullname 
     { 
      get 
      { 
       return Firstname + " " + Lastname; 
      } 
     } 
    } 
} 
+0

尝试使用ObservableCollection <>代替List <>。 此外 - 单击按钮事件不能在视图的代码隐藏。尝试绑定事件。 (这是MVVM) – Niewidzialny

+0

我将如何去绑定,虽然?也感谢Allot –

+0

看看这里:) https://channel9.msdn.com/Series/Windows-Phone-8-1-Development-for-Absolute-Beginners/Part-18-Understanding-MVVM-ObservableCollection-T -and-INotifyPropertyChanged – Niewidzialny

回答

0

在视图模型中,有两种基本方法可以让绑定目标(一个xaml控件)知道绑定源(您的属性)发生了某些感兴趣的事情。首先是通过视图模型的INotifyProperty的实现更改,您的视图模型通过为Persons属性提供属性更改通知来正确实现。

但是,简单地将一个成员添加到列表中并不构成对Persons属性本身的更改;只有当您通过属性设置器更改该属性时才会发生这种情况,List.Add不会这样做。

需要的是集合通知绑定目标集合中的某些内容发生了变化的方法,这是集合本身通过实现INotifyCollectionChanged接口完成的,List没有这样做。幸运的是,框架提供了实现这些接口的ObservableCollection,因此只需将List更改为ObservableCollection即可。

请参考this question了解关于ObservableCollectionT>的很多答案。