[英]Refresh ObservableCollection<T> when a property in T changes - WPF MVVM
我有一個ListBox
,它綁定到視圖模型中的ObservableCollection<Series>
。 每次用戶單擊“刪除”按鈕時,都會在Series
類內部執行特定項目的Delete
DelegateCommand
,並將該項目從數據庫中刪除。
我正在尋找發生這種情況時更新ObservableCollection<Series>
,以便在刪除相關項目后立即將其從XAML視圖中刪除。
目前這還沒有發生,我是WPF的新手,已經嘗試了好幾天了,請指出我要去哪里錯誤:
相關XAML:
<ListBox ItemsSource="{Binding SeriesCollection}" Name="lbSeries" Background="#6E7587" ItemContainerStyle="{StaticResource highlightStyle}" SelectionMode="Single" AlternationCount="2" Grid.Row="2" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Margin="5,0" FontSize="14" Name="txtName" Text="{Binding Name}" Width="190" Height="30" Grid.Column="0" />
<wpfToolkit:IntegerUpDown Value="{Binding Season}" Name="nudSeason" FontSize="14" Height="30" Width="95" Increment="1" Maximum="100000" Minimum="0" Grid.Column="1" />
<wpfToolkit:IntegerUpDown Value="{Binding Episode}" Name="nudEpisode" FontSize="14" Height="30" Width="95" Increment="1" Maximum="100000" Minimum="0" Grid.Column="2" />
<Button Command="{Binding Save}" Grid.Column="3" Width="60" Height="50" Cursor="Hand" ToolTip="Save program" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image Source="Resources\Save.png" Width="30" Height="40" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Command="{Binding Delete}" Grid.Column="4" Width="60" Height="50" Cursor="Hand" CommandParameter="{Binding ElementName=lbSeries,Path=SelectedItem}" ToolTip="Remove program" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="15,0">
<Button.Template>
<ControlTemplate>
<Border HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image Source="Resources\Delete.png" Width="30" Height="40" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Label Content="{Binding Information}" Grid.Column="5" FontSize="14" Margin="10,0" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
查看模型:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using SeriesTracker.Functions;
using System.Linq;
namespace SeriesTracker.Client
{
public class SeriesTrackerViewModel : INotifyPropertyChanged
{
public DelegateCommand NewSeries { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Series> _series = new ObservableCollection<Series>();
public ObservableCollection<Series> SeriesCollection
{
get { return _series; }
set
{
_series = value;
RaisePropertyChanged("SeriesCollection");
}
}
public SeriesTrackerViewModel()
{
NewSeries = new DelegateCommand(AddNewSeries);
DataTable table = DataAccessLayer.GetSeries();
if (table.Rows.Count > 0)
LoadSeries(table);
}
private void LoadSeries(DataTable table)
{
foreach (DataRow row in table.Rows)
{
int id = Int32.Parse(row["Id"].ToString());
string name = row["Name"].ToString();
int season = 0;
int episode = 0;
if (Int32.TryParse(row["Season"].ToString(), out season) &&
Int32.TryParse(row["Episode"].ToString(), out episode))
{
var series = new Series(id, name, season, episode);
SeriesCollection.Add(series);
}
}
}
public void AddNewSeries()
{
SeriesCollection.AddSeries();
}
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
系列類別:
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace SeriesTracker.Functions
{
public class Series : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private DelegateCommand _save;
public DelegateCommand Save
{
get { return _save; }
set
{
_save = value;
RaisePropertyChanged("Save");
}
}
private DelegateCommand _delete;
public DelegateCommand Delete
{
get{return _delete;}
set
{
_delete = value;
RaisePropertyChanged("Delete");
}
}
public int Id { get; set; }
string _name;
public String Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
int _season;
public Int32 Season
{
get { return _season; }
set
{
_season = value;
RaisePropertyChanged("Season");
}
}
int _episode;
public Int32 Episode
{
get { return _episode; }
set
{
_episode = value;
RaisePropertyChanged("Episode");
}
}
string _information;
public String Information
{
get { return _information; }
set
{
_information = value;
RaisePropertyChanged("Information");
}
}
public Series(int id,string name,int season, int episode)
{
Id = id;
Name = name;
Season = season;
Episode = episode;
Save = new DelegateCommand(SaveItem);
Delete = new DelegateCommand(DeleteItem);
}
public void DeleteItem()
{
var selectedItem = this;
if (selectedItem.Id != -1)
{
DataAccessLayer.Delete(selectedItem.Id);
}
}
public void SaveItem()
{
var selectedItem = this;
if (selectedItem.Id == -1)
DataAccessLayer.AddEntry(selectedItem.Name,selectedItem.Season,selectedItem.Episode);
else
DataAccessLayer.Update(selectedItem.Id,
selectedItem.Name,selectedItem.Season,selectedItem.Episode);
}
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
您不應將DeleteCommand保留在Series類中,而應將其放在視圖模型上。
在視圖模型中,您可以輕松更新ObservableCollection。
您需要在ViewModel上使用類型系列的泛型委托命令,在XAML上,需要在命令Parameter上傳遞{Binding}。
查看模型C#:-
DelegateCommand<Series> DeleteCommand { get; set; }
DeleteCommand = new RelayCommand<Series>(OnDelete);
// This method will gets execute on click the of Delete Button1
private void OnDelete(Series series)
{
}
XAML:-在“刪除”按鈕上更改綁定和命令參數值
CommandParameter =“ {Binding}”
Command =“ {Binding DataContext.DeleteCommand,RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type Window}}}”“
希望這個能對您有所幫助
您可以訂閱ObservableCollection
中每個系列的PropertyChangedEventHandler
,然后在事件觸發時調用RaisePropertyChanged("SeriesCollection")
更新:我的意思是這樣的:
private void LoadSeries(DataTable table)
{
...
{
var series = new Series(id, name, season, episode);
series.PropertyChanged += { RaisePropertyChanged("SeriesCollection"); }
SeriesCollection.Add(series);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.