在更新可观察集合中的对象时,Xaml视图不会更新

时间:2016-06-01 18:04:49

标签: xaml uwp uwp-xaml

我正在尝试开始使用UWP应用程序,尽管我对xaml和C#完全陌生。这个问题现在花了我几个小时。我已经看了很多教程并在stackoverflow上阅读了类似问题的答案,但到目前为止我没有任何工作。

我有一个ListView,它有一个ObservableCollection的数据绑定。当我启动应用程序时,它会正确显示此集合中的对象。当我向集合中添加新对象或删除现有对象时,ListView会正确更新。但是当我修改对象时,虽然我实现了INotifyPropertyChanged并且在属性发生变化时触发了事件,但它并没有更新。

以下是代码:

查看Xaml

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

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel x:Name="firstStack" Margin="8 ,32 ,0, 0 " Width="350" >
        <ListView ItemsSource="{x:Bind ViewModel.Collection}"   VerticalAlignment="Center" Background="Yellow" CanReorderItems="True">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="data:Challenge" >
                    <Grid  Background="Green" >
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="50"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Button  Content="+" Grid.Column="0"/>
                        <TextBlock  Grid.Column="1" Text="{x:Bind ChallengeName}" VerticalAlignment="Center"/>
                        <TextBlock Grid.Column="2"  Text="{x:Bind Progress}" VerticalAlignment="Center" HorizontalAlignment="Center" />
                        <Button Grid.Column="3" Content="X"  />
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Content="Add" Click="add"/>
        <Button Content="Delete" Click="delete"/>
        <Button Content="Update Progress" Click="updateProgress"/>
    </StackPanel>
</Grid>

代码背后

    using Prophecy_Challenge_Tracker.persistence;
using Prophecy_Challenge_Tracker.viewmodel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
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;

namespace Prophecy_Challenge_Tracker
{
    /// <summary>
    /// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
    /// </summary>
    public sealed partial class MainPage : Page
    {

        public MainPage()
        {
            this.ViewModel = new Viewmodel();
            this.InitializeComponent();
            this.DataContext = ViewModel;
        }

        public Viewmodel ViewModel { get; set; }

        int counter = 2;
        private void add(object sender, RoutedEventArgs e)
        {
            counter++;
            var c = new Challenge();
            c.ChallengeName = "Additional Line";
            c.Progress = counter + "/7";
            ViewModel.Collection.Add(c);
        }

        private void delete(object sender, RoutedEventArgs e)
        {
         var c =   ViewModel.Collection.ElementAt(ViewModel.Collection.Count - 1);
            ViewModel.Collection.Remove(c);
            counter--;
        }

        private void updateProgress(object sender, RoutedEventArgs e)
        {
            var c = ViewModel.Collection.ElementAt(ViewModel.Collection.Count - 1);
            int index = ViewModel.Collection.IndexOf(c);
            counter++;
            Debug.WriteLine("CurrentName: " + c.Progress);
            c.Progress = counter + "/7";
            Debug.WriteLine("New Name: " + c.Progress);
        }
    }
}

对象类

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Prophecy_Challenge_Tracker.persistence
{
    public class Challenge : INotifyPropertyChanged
    {
        private string challengeName;
        public string ChallengeName
        {
            get { return challengeName; }
            set
            {
                if (value != challengeName)
                {
                    challengeName = value;
                    NotifyPropertyChanged("ChallengeName");
                }
            }
        }

        private string progress = "";
        public string Progress
        {
            get { return progress; }
            set
            {
                if (value != progress)
                {
                    progress = value;
                    NotifyPropertyChanged("Progress");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged([CallerMemberName]string propertyName = "")
        {
            System.Diagnostics.Debug.WriteLine("Shortly before update. PropertyName = " + propertyName);
            if (PropertyChanged != null)
            {
                System.Diagnostics.Debug.WriteLine("Update now");
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

视图模型

using Prophecy_Challenge_Tracker.persistence;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Prophecy_Challenge_Tracker.viewmodel
{
    public class Viewmodel
    {

        public ObservableCollection<Challenge> Collection { get; set; }

        public Viewmodel()
        {
            System.Diagnostics.Debug.WriteLine("New Viewmodel is being created");
            Collection = new ObservableCollection<Challenge>();
            Challenge c = new Challenge();
            c.ChallengeName = "First Line";
            c.Progress = "1/5";
            Collection.Add(c);
            c = new Challenge();
            c.ChallengeName = "Second Line";
            c.Progress = "2/5";
            Collection.Add(c);
        }
    }
}

1 个答案:

答案 0 :(得分:6)

编译的绑定默认为OneTime,因此它们最初只设置,不会监听更改。

将其更改为:

<ListView ItemsSource="{x:Bind ViewModel.Collection, Mode=OneWay}">...

this Build session中找到关于编译绑定的一个很好的概述。