我希望这里的任何人都可以帮助我动态绑定数据。当我在按钮上添加列表项时单击它不会在我的页面中更新,这也是为int添加值。然而,当我输入文本框时,int会发生变化...所以我不明白出了什么问题。我也不知道这是否是正确的方法。
因此,要快速了解我的问题:
假定的错误位置: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 :(得分:0)
在视图模型中,有两种基本方法可以让绑定目标(xaml控件)知道绑定源(您的属性)发生了一些有趣的事情。第一种是通过视图模型的INotifyProperty实现更改,您的视图模型通过为Persons属性提供属性更改通知来正确实现。
但只是在列表中添加成员并不构成对Persons属性本身的更改;只有当您通过属性设置器更改该属性时才会发生这种情况,而List.Add不会这样做。
需要的是集合通知绑定目标集合中的某些内容已经发生变化的方式,并且集合本身通过实现INotifyCollectionChanged接口来完成,而List不这样做。幸运的是,框架提供了实现这些接口的ObservableCollection,因此只需将List更改为ObservableCollection就可以为您完成。
有关ObservableCollectionT&gt;的大量答案,请参阅this question。