Wpf Beobachtbaren Sammlung und DataGrid keine Aktualisierung verpasst
Ich habe eine observable-collection in der Ansicht Modell, die Bindbare Basis wie folgt Bitte haben Sie einen Blick auf die MoveUp und MoveDown Methoden, bei denen Sie gebunden sind, um zwei Schaltflächen in der Ansicht. Wenn Sie jemals up-Taste gedrückt wird, möchte ich die ausgewählte Zeile in der datagrid-Schritt für Schritt bis in das basierend auf der Reihenfolge der Spalte in der Datenbank und für unten, einen Schritt nach unten.. Beide Methoden funktioniert PERFEKT. Problem ist, die änderungen angezeigt bekommt, in dem datagrid nur, wenn die gesamte Ansicht aktualisiert wird. Meine Forderung ist, wenn der button angeklickt wird, möchte ich die Ansicht automatisch aktualisiert. Ich entschuldige mich für diese lange code. Bitte Um Hilfe!!!!!. Ich habe einige cs-code als auch für die beiden up-und down-Tasten die unten angegebene viewmodel. Nur Zeiger in den code, muss betont werden, ist die ObservableCollection JobEntities, MoveUp und MoveDown Befehle.
ViewModel.cs:
public class JobConfigurationViewModel : BindableBase
{
public JobConfigurationLogic JobConfigurationLogic =
new JobConfigurationLogic(new JobConfigurationResultsRepository());
public SrcDestConfigurationLogic SrcDestConfigurationLogic =
new SrcDestConfigurationLogic(new SrcDestCofigurationRepository());
private string _enterprise;
public string Enterprise
{
get { return _enterprise; }
set { SetProperty(ref _enterprise, value); }
}
private int currentJobID;
private int currentSequence;
private int previousJobID;
private int previousSequence;
private string _site;
public string Site
{
get { return _site; }
set { SetProperty(ref _site, value); }
}
private int _siteID;
public int SiteID
{
get { return _siteID; }
set { SetProperty(ref _siteID, value); }
}
private ObservableCollection<JobConfigurationResults> _jobEntities;
public ObservableCollection<JobConfigurationResults> JobEntities
{
get { return _jobEntities; }
set
{
SetProperty(ref _jobEntities, value);
this.OnPropertyChanged("JobEntities");
}
}
//Source System List for Job
private List<SourceSiteSystem> _lstJobSrcSystems;
public List<SourceSiteSystem> LstJobSrcSystems
{
get { return _lstJobSrcSystems; }
set
{
//Using bindable base setproperty method instead of older inotify prop changed method
SetProperty(ref _lstJobSrcSystems, value);
}
}
//Deestination System List for Job
private List<DestinationSiteSystem> _lstJobDestSystems;
public List<DestinationSiteSystem> LstJobDestSystems
{
get { return _lstJobDestSystems; }
set
{
//Using bindable base setproperty method instead of older inotify prop changed method
SetProperty(ref _lstJobDestSystems, value);
}
}
//the Selected Source Site system ID
private int _selectedSrcSiteSystemId = 0;
public int SelectedSrcSiteSystemId
{
get { return _selectedSrcSiteSystemId; }
set
{
//Using bindable base setproperty method instead of older inotify prop changed method
SetProperty(ref _selectedSrcSiteSystemId, value);
}
}
//the Selected Source Site system from the dropdown
private SourceSiteSystem _selectedSrcSiteSystem;
public SourceSiteSystem SelectedSrcSiteSystem
{
get { return _selectedSrcSiteSystem; }
set
{
//Using bindable base setproperty method instead of older inotify prop changed method
if (value != null)
{
SetProperty(ref _selectedSrcSiteSystem, value);
SelectedSrcSiteSystemId = SelectedSrcSiteSystem.SiteSystemId;
}
}
}
//the Selected Destination Site system ID
private int _selectedDestSiteSystemId = 0;
public int SelectedDestSiteSystemId
{
get { return _selectedDestSiteSystemId; }
set
{
//Using bindable base setproperty method instead of older inotify prop changed method
SetProperty(ref _selectedDestSiteSystemId, value);
}
}
//the Selected Destination Site system from the dropdown
private DestinationSiteSystem _selectedDestSiteSystem;
public DestinationSiteSystem SelectedDestSiteSystem
{
get { return _selectedDestSiteSystem; }
set
{
//Using bindable base setproperty method instead of older inotify prop changed method
if (value != null)
{
SetProperty(ref _selectedDestSiteSystem, value);
SelectedDestSiteSystemId = SelectedDestSiteSystem.SiteSystemId;
}
}
}
private JobConfigurationResults _jeJobConfigurationResults;
public JobConfigurationResults JEJobConfigurationResults
{
get { return _jeJobConfigurationResults; }
set { _jeJobConfigurationResults = value; }
}
private List<JobTaskConfiguration> _taskSelectionList = new List<JobTaskConfiguration>();
private CancellationTokenSource _source;
private RelayCommand<object> _commandSaveInstance;
private RelayCommand<object> _hyperlinkInstance;
private RelayCommand<object> _commandRunJob;
private RelayCommand<object> _upCommand;
private RelayCommand<object> _downCommand;
private IEventAggregator _aggregator;
///<summary>
///This is a Subscriber to the Event published by EnterpriseViewModel
///</summary>
///<param name="agg"></param>
public JobConfigurationViewModel(IEventAggregator agg)
{
_aggregator = agg;
PubSubEvent<Message> evt = _aggregator.GetEvent<PubSubEvent<Message>>();
evt.Subscribe(message => Enterprise = message.Enterprise.ToString(), ThreadOption.BackgroundThread);
evt.Subscribe(message => Site = message.Site.ToString(), ThreadOption.BackgroundThread);
evt.Subscribe(message => SiteID = message.SiteID, ThreadOption.BackgroundThread);
//evt.Unsubscribe();
StartPopulate();
}
private async void StartPopulate()
{
await TaskPopulate();
}
//This is to ensure that the publisher has published the data that is needed for display in this workspace
private bool TaskProc()
{
Thread.Sleep(500);
PubSubEvent<Message> evt = _aggregator.GetEvent<PubSubEvent<Message>>();
evt.Subscribe(message => Enterprise = message.Enterprise.ToString(), ThreadOption.BackgroundThread);
evt.Subscribe(message => Site = message.Site.ToString(), ThreadOption.BackgroundThread);
evt.Subscribe(message => SiteID = message.SiteID, ThreadOption.BackgroundThread);
return DoPopulate();
}
private Task<bool> TaskPopulate()
{
_source = new CancellationTokenSource();
return Task.Factory.StartNew<bool>(TaskProc, _source.Token);
}
///<summary>
///This method handles the populating of the Source and Destination Dropdowns and the Job entity and Task Datagrid
/// This is mainly driven by the Site selected in the previous workspace
///</summary>
///<returns></returns>
private bool DoPopulate()
{
PopulateSourceDestinations(this.SiteID);
return true;
}
///<summary>
///this method displays all entities and tasks for the site.
///This is done async so that the Publisher thread is not held up
///</summary>
public void GetJobConfigurationResults()
{
if (SelectedSrcSiteSystem == null)
{
SelectedSrcSiteSystem = LstJobSrcSystems[0];
}
if (SelectedDestSiteSystem == null)
{
SelectedDestSiteSystem = LstJobDestSystems[0];
}
SelectedSrcSiteSystemId = SelectedSrcSiteSystem.SiteSystemId;
SelectedDestSiteSystemId = SelectedDestSiteSystem.SiteSystemId;
var jobConfigurationResults = new JobConfigurationResults
{
SourceId = SelectedSrcSiteSystemId,
DestinationId = SelectedDestSiteSystemId
};
JobEntities = new ObservableCollection<JobConfigurationResults>();
JobEntities = JobConfigurationLogic.GetResults(jobConfigurationResults.SourceId,
jobConfigurationResults.DestinationId);
_taskSelectionList = new List<JobTaskConfiguration>(JobEntities.Count * 3);
}
///<summary>
/////Adding a method to pupulate the Source and Destination dropdown lists.
///This is done async so that the Publisher thread is not held up
///</summary>
///
///
public async void PopulateSourceDestinations(int siteId)
{
this.LstJobSrcSystems = SrcDestConfigurationLogic.LoadSourceSiteSystems(siteId);
this.LstJobDestSystems = SrcDestConfigurationLogic.LoadDestinationSystems(siteId);
GetJobConfigurationResults();
}
public ICommand HyperlinkCommand
{
get
{
if (_hyperlinkInstance == null)
_hyperlinkInstance = new RelayCommand<object>(openDialog);
return _hyperlinkInstance;
}
}
private void openDialog(object obj)
{
JobConfigurationResults results = obj as JobConfigurationResults;
JEJobConfigurationResults = JobEntities.SingleOrDefault(x => x.JobEntityId == results.JobEntityId);
}
public ICommand CommandSave
{
get
{
if (_commandSaveInstance == null)
_commandSaveInstance = new RelayCommand<object>(saveJobConfigurationChanges);
return _commandSaveInstance;
}
}
public ICommand CommandRunJob
{
get { return _commandRunJob ?? (_commandRunJob = new RelayCommand<object>(RunJob)); }
}
///<summary>
///this saves all the changes in the selection made by the user
///</summary>
///<param name="ob"></param>
public void saveJobConfigurationChanges(object ob)
{
foreach (var job in JobEntities)
{
int jobEntityId = job.JobEntityId;
foreach (var task in job.TaskDetails)
{
int id = task.JobTask_ID;
bool isSelected = task.IsSelected;
_taskSelectionList.Add(task);
}
}
JobConfigurationLogic.UpdateTaskSelection(_taskSelectionList);
}
public ICommand UpCommand
{
get
{
if (_upCommand == null)
_upCommand = new RelayCommand<object>(MoveUp);
return _upCommand;
}
}
private void MoveUp(object obj)
{
if (obj != null)
{
JobConfigurationResults results = obj as JobConfigurationResults;
currentJobID = results.JobEntityId;
currentSequence = results.SequenceOrder - 1;
try
{
JobConfigurationResults res = _jobEntities.SingleOrDefault(n => n.SequenceOrder == currentSequence);
previousJobID = res.JobEntityId;
previousSequence = res.SequenceOrder + 1;
//JobConfigurationLogic.UpdateSequence(currentJobID, previousSequence, previousJobID, currentSequence);
JobConfigurationLogic.UpdateSequence(currentSequence, currentJobID, previousSequence, previousJobID);
OnPropertyChanged("JobEntities");
}
catch (NullReferenceException)
{
MessageBox.Show("Can't move the top record");
}
}
else
{
MessageBox.Show("Please Select a row that you want to sort");
}
}
public ICommand DownCommand
{
get
{
if (_downCommand == null)
_downCommand = new RelayCommand<object>(MoveDown);
return _downCommand;
}
}
private void MoveDown(object obj)
{
if (obj != null)
{
JobConfigurationResults results = obj as JobConfigurationResults;
currentJobID = results.JobEntityId;
currentSequence = results.SequenceOrder + 1;
try
{
JobConfigurationResults res = _jobEntities.SingleOrDefault(a => a.SequenceOrder == currentSequence);
previousJobID = res.JobEntityId;
previousSequence = res.SequenceOrder - 1;
JobConfigurationLogic.UpdateSequence(currentSequence, currentJobID, previousSequence, previousJobID);
OnPropertyChanged("JobEntities");
}
catch (NullReferenceException)
{
MessageBox.Show("You have reached the end");
}
}
else
{
MessageBox.Show("Please Select a row that you want to sort");
}
}
///<summary>
///Execute an etl job using the current job id
///</summary>
private void RunJob(object obj)
{
JobEngine jobEngine = new JobEngine();
var jobId = JobEntities[0].JobId;
jobEngine.ProcessJob(jobId);
}
}
CS CODE:
private void btnup_Click(object sender, RoutedEventArgs e)
{
dgEntities.Items.Refresh();
//dgEntities.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget();
}
private void btndown_Click(object sender, RoutedEventArgs e)
{
dgEntities.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget();
}
Yup, für datagrid itemsource=JobEntities.. Alle Befehle funktionieren tadellos. Nur das datagrid ist nicht erfrischend.
InformationsquelleAutor nikhil | 2014-11-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer
ObservableCollection
informieren auf ändern. Es gibt keinen Grund, es manuell zu tun, so können Sie entfernen Sie alleOnPropertyChanged("JobEntities");
. Dadurch erhalten Sie eine saubere Lösung.MSDN
Den nächsten Teil ist, eine ObservableCollection nur Benachrichtigungen bei änderungen zu der Sammlung selbst (hinzufügen/entfernen). Änderungen an einem element innerhalb der Liste nicht haben, haben die notify-Nachricht gesendet. Um dies zu tun, die einfachste Methode ist die Implementierung der
INotifyPropertyChanged
zu den Elementen, die in der Beobachtbaren SammlungIch bin mit PRISMA 5 im Beispiel, so sollte es ziemlich gleich, was du tust. Es gibt ein paar wesentliche design-änderungen, um Sie code. Zunächst, ich bin mit einem gerade Sachen für mein Beobachtbaren Sammlung. Wir wissen, dass das framework kümmert sich um alle hinzufügen/entfernen von Vorgängen in dieser Sammlung. Dann zu Benachrichtigen, wenn ich eine Eigenschaft in der Entität in eine observable-collection, die ich verwendet habe, eine notify-Eigenschaft innerhalb der
TestEntity
Klasse selbst.Hier ist meine Einheit, beachten Sie die
BindableBase
und die Tatsache, dass ich benachrichtigt ändern. Dies ermöglicht es derDataGrid
oder was auch immer Sie verwenden, um benachrichtigt zu werden, dass die Eigenschaft geändert hat.Nun wirklich alle
TestEntity
muss umgesetzt haben, dieINotifyPropertyChanged
für diese zu arbeiten, aber ich bin mit dem PRISMABindableBase
als Beispiel.BEARBEITEN
Fand ich eine ähnliche Frage. Ich denke, deins ist etwas anders, aber Sie überschneiden sich auf die Konzepte. Es kann helfen, sich über es.
Observable Collection Benachrichtigen, wenn die Eigenschaft geändert in MVVM
BEARBEITEN
Wenn das datagrid-Steuerelement sortiert die Vorherige Methode nicht aktualisieren Sie das raster. Um dies zu umgehen, müssen Sie aktualisieren Sie die grid-Ansicht, aber nicht direkt zugreifen, mithilfe von MVVM. So zu handhaben, Sie werden wollen, zu einem
CollectionViewSource
.Den
TestEntity
Klasse nicht ändern, aber hier ist die Klasse wieder:Zur Klarstellung, hier ist mein XAML zeigt die Bindung an die neue
CollectionViewSource
.Zur weiteren Lektüre finden Sie in der MSDN Artikel auf dieser.
Hier ist eine weitere relevante Frage/Antwort - Re-Art WPF DataGrid nach begrenzt Daten geändert hat
Nathan ich habe versucht, diese aber noch nicht erfrischend DataGrid. Seine Arbeit nur auf, wenn ich aktualisieren Sie die gesamte Ansicht. Gibt es eine Möglichkeit um die Ansicht zu aktualisieren, auf die Schaltfläche klicken..
Tut mir Leid, ich muß fehlen, was Sie zu tun versuchen. Was habe ich Ihnen gezeigt wird, aktualisieren Sie den Bildschirm, wenn Sie ändern Elemente innerhalb des beobachtbaren Sammlung, die zu sein scheint, was Sie zu tun versuchen. Die einzige andere Stück konnte ich sehen, haben Sie möglicherweise bekam das datagrid sortiert, in dem Fall wird das raster nicht update-und resort-Elemente. Also werde ich update meine Antwort, um für dieses Konto.
Ich habe ein neues Stück, um den code, es verwendet nun eine
CollectionViewSource
zu behandeln aktualisieren des Rasters. Hoffentlich ist das, was Sie nach.Hey Nathan, ich versuche das ViewSource.Ansicht, aber das problem ist seine nicht anzeigen jedem Datensatz im DataGrid. Auf der anderen Seite, wenn ich nur binden die Observable Collection zeigt es alle Datensätze in datagrid. Ich hielt auch die Bruchstelle und die Anzahl der für die ViewSource ist die gleiche wie die Beobachtbaren Sammlung, aber für einige Grund es dosent display-alle Zeilen im datagrid.
InformationsquelleAutor Nathan