[英]refresh bindings in itemscontrol wpf
我有一個簡單的項控件綁定到條目對象列表。 該按鈕更新列表中每個項目的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>
然后,您必須重寫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>
:
namespace TestItemsControl
{
public class TestViewModel
{
public ObservableCollection<Entry> Entries=new ObservableCollection<Entry>();
public ICommand UpdateCmd { get; set; }
public TestViewModel()
{
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 });
}
}
}
這樣,您不必調用Refesh函數。
如果沒有人訂閱活動,則必須檢查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"));
}
}
}
我認為您必須在這里選擇:
創建這樣的方法:
protected void OnPropertyChanged(string) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } }
然后,每當您要更新屬性時,都可以:
OnPropertyChanged("TheNameOfTheProperty");
或者如果您想更新該類中的每個屬性:
OnPropertyChanged(string.Empty);
如果不確定何時更新哪個屬性,建議您選擇后者。
您沒有綁定UpdateCmd並在任何地方調用Refresh,除非它在Click處理程序中,但是您應該使用MVVM方法來執行此操作。
將Click事件處理程序更改為來自xaml中的viewmodel的命令綁定,如下所示
<Button Grid.Row="1" Content="Update" Command={Binding UpdateCmd}/>
然后在視圖模型的構造函數綁定中,創建一個新的RelayCommand或ICommand實現類的樣子,以便構造器接收動作委托。
this.UpdateCmd = new RelayCommand(this.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並在屬性設置器上引發事件,綁定將被更新,而不會通知整個集合應被更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.