2017-04-15 89 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>的很多答案。