Il mio progetto è basato sul pattern MVVM.Come aggiornare l'interfaccia utente in MVVM WPF
Ho costruito una vista ad albero che mostra il mio file system. Ogni cartella ha una casella per selezionare la cartella corrente. Il processo di selezione richiede un po 'di tempo, mentre l'operazione è in esecuzione, c'è un pulsante che è disabilitato e al termine dell'operazione sto abilitando il pulsante.
Il mio problema è che quando il pulsante diventa "disabilitato" lo vedo immediatamente. Tuttavia, quando il pulsante ritorna alla modalità abilitata, devo agire (come il clic del mouse) per vedere il pulsante abilitato.
Come posso verificare che l'interfaccia utente venga aggiornata immediatamente dopo l'attivazione del pulsante?
Questi sono i miei pulsanti:
<Button Content="<- Back" Margin="5,0,5,0" Width="80" Height="25"
IsEnabled="{Binding CanMoveToPreviousPage, UpdateSourceTrigger=PropertyChanged}"
Command="{Binding Path=NavigateBackCommand, IsAsync=True}" />
<Button Content="{Binding ButtonNextCaption}" Margin="5,0,5,0" Width="80" Height="25"
IsEnabled="{Binding CanMoveToNextPage, UpdateSourceTrigger=PropertyChanged}"
Command="{Binding Path=NavigateNextCommand, IsAsync=True}" />
Nel mio ViewModel ho aggiunto questo codice:
public bool CanMoveToNextPage
{
get
{
return this.CurrentPage != null && this.CurrentPage.CanMoveNext;
}
set
{
if (CurrentPage != null)
{
this.CurrentPage.CanMoveNext = value;
OnPropertyChanged("CanMoveToNextPage");
}
}
}
public bool CanMoveToPreviousPage
{
get { return 0 < this.CurrentPageIndex && CurrentPage.CanMoveBack; }
set
{
if (CurrentPage != null)
{
this.CurrentPage.CanMoveBack = value;
OnPropertyChanged("CanMoveToPreviousPage");
}
}
}
aggiornare l'interfaccia utente avviene subito dopo eseguo un clic del mouse o qualsiasi combinazione di tasti.
Questo è il codice dell'azione che viene disattivazione e attivazione dei pulsanti:
void bg_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
DecrementDoneCounter();
if (ThreadSafeCouner == 0)//means all bg workers are done
{
UIlimitation(true);
}
}
private int ThreadSafeCouner; // check how many bgworkers run
public void IncrementDoneCounter() { Interlocked.Increment(ref ThreadSafeCouner); }
public void DecrementDoneCounter() { Interlocked.Decrement(ref ThreadSafeCouner); }
void bg_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
IncrementDoneCounter();
UIlimitation(false);
((bgArguments)e.Argument).SelectedDirectory.CanSelected = false;
MarkItems(((bgArguments)e.Argument).SelectedDirectory, ((bgArguments)e.Argument).IsSelect);
((bgArguments)e.Argument).FreeWorkerAllocation();
((bgArguments)e.Argument).SelectedDirectory.CanSelected = true;
}
//this is the enabling action which execute the propeties setters at the upper part of this post
private static void UIlimitation(bool limit)
{
MainWindowViewModel.Instance.CanMoveToNextPage = limit;
MainWindowViewModel.Instance.CanMoveToPreviousPage = limit;
}
Cosa posso fare?
cercano this.UpdateLayout() o ButtonsParent.UpdateLayout() –
Quando l'operazione è fatta stai alzando l'evento 'OnPropertyChanged' per le proprietà interessata per attivare/disattivare il pulsante? –
Quando ho finito ho cambiato la proprietà abilitata ma Set {...} e Set {} includono l'evento OnPropertyChanged. Quando provo a eseguire il debug, tutto funziona perfettamente e il pulsante viene abilitato senza fare clic. Posso capire quale sia il problema – Ofir