windows存储动态数据绑定列表和其他类型

时间:2017-04-15 16:54:12

标签: c# xaml windows-store-apps

我希望这里的任何人都可以帮助我动态绑定数据。当我在按钮上添加列表项时单击它不会在我的页面中更新,这也是为int添加值。然而,当我输入文本框时,int会发生变化...所以我不明白出了什么问题。我也不知道这是否是正确的方法。

因此,要快速了解我的问题:

  1. 为什么这不起作用?
  2. 这是正确的方法吗?
  3. 有人可以告诉我如何让它发挥作用吗?
  4. 假定的错误位置: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;
                }
            }
        }
    }
    

1 个答案:

答案 0 :(得分:0)

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

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

需要的是集合通知绑定目标集合中的某些内容已经发生变化的方式,并且集合本身通过实现INotifyCollectionChanged接口来完成,而List不这样做。幸运的是,框架提供了实现这些接口的ObservableCollection,因此只需将List更改为ObservableCollection就可以为您完成。

有关ObservableCollectionT&gt;的大量答案,请参阅this question