刷新itemscontrol wpf中的绑定

时间:2016-02-23 06:59:56

标签: c# wpf refresh itemscontrol

我有一个简单的itemscontrol绑定到Entries对象列表。该按钮更新列表中每个项目的LastUpdated。如何引发属性更改事件,以便在ItemsControl中更新LastUpdated字段。我简化了我的例子,只是想弄清楚绑定问题。我的真实样本使用PRISM和第三方控件。

C#代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;

namespace TestItemsControl
{
    public class Entry
    {
        public string Name { get; set; }

        public DateTime LastUpdated { get; set; }
    }
}

namespace TestItemsControl
{
    public class TestViewModel: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public List<Entry> Entries { get; set; }

        public ICommand UpdateCmd { get; set; }

        public TestViewModel()
        {
            this.Entries = new List<Entry>();
            this.Entries.Add(new Entry{ Name = "1", LastUpdated = DateTime.Now });
            this.Entries.Add(new Entry { Name = "2", LastUpdated = DateTime.Now });
            this.Entries.Add(new Entry { Name = "3", LastUpdated = DateTime.Now });
        }

        public void Refresh()
        {
            if (this.PropertyChanged!= null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Entries"));
            }
        }
    }
}

XAML:

<Application x:Class="TestItemsControl.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestItemsControl"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:TestViewModel x:Key="viewModel"/>
    </Application.Resources>
</Application>


<Window x:Class="TestItemsControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestItemsControl"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" DataContext="{StaticResource viewModel}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ItemsControl Grid.Row="0" ItemsSource="{Binding Entries}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding Name}"/>
                        <TextBlock Text="{Binding LastUpdated}"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Grid.Row="1" Content="Update" Click="Button_Click"/>
    </Grid>
</Window>

4 个答案:

答案 0 :(得分:1)

然后你必须重写你的let myList:[Int] = [] myList.toObservable() .switchIfEmpty { () in // <- Not (yet?) implemented return Observable.of(1) }.subscribeNext { num in print(num) } // prints 1

Entry

另外,将public class Entry: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public string Name { get; set; } DateTime lastUD; public DateTime LastUpdated { get { return lastUD; } set { lastUD = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("LastUpdated")); } } } 更改为List<Entry>

ObservableCollection<Entry>

这样您就不必调用Refesh功能。

答案 1 :(得分:1)

如果没有人订阅活动,你必须检查Null

public class Entry : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string Name { get; set; }

    DateTime lastUD;
    public DateTime LastUpdated
    {
        get
        {
            return lastUD;
        }
        set
        {
            lastUD = value;
            if(PropertyChanged != NULL)
               PropertyChanged(this, new PropertyChangedEventArgs("LastUpdated"));
        }
    }
}

答案 2 :(得分:1)

我认为你必须在这里做出选择:

  1. 创建一个这样的方法:

    protected void OnPropertyChanged(string) 
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
  2. 然后,无论何时您想要更新房产,都可以:

    OnPropertyChanged("TheNameOfTheProperty");
    

    或者如果要更新班级中的每个属性:

    OnPropertyChanged(string.Empty);
    

    如果您不确定要更新哪个属性,我建议您使用后者。

    1. 你可以,但我建议你不要这样做:实例化一个新列表,添加更新的值,清除原始列表,将原始列表设置为新列表,然后更新列表的属性名称。

答案 3 :(得分:1)

您没有绑定UpdateCmd并在任何地方调用Refresh,除非它在Click处理程序中,但您应该使用MVVM方法来执行此操作。

将Click事件处理程序更改为xaml中viewmodel的命令绑定,如此

<Button Grid.Row="1" Content="Update" Command={Binding UpdateCmd}/>

然后在viewmodel的构造函数中,绑定创建一个新的RelayCommand或者ICommand实现类是什么样的,这样构造函数就会接受动作委托。

this.UpdateCmd  = new RelayCommand(this.Update);

此外,您应该将Refresh更改为Update,以更新条目的时间戳。

public void Update()
{
    foreach (var entry in this.Entries)
    {
        entry.LastUpdated = DateTime.Now;
    }

    if (this.PropertyChanged!= null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs("Entries"));
    }
}

但是你应该只在Entry模型上实现INotifyPropertyChanged并在属性设置器上引发事件,绑定会更新而不会通知整个集合应该更新。