2012-10-02 17 views
5

Mi proyecto se basa en el patrón MVVM.¿Cómo puedo actualizar la interfaz de usuario en MVVM WPF

He creado una vista de árbol que muestra mi sistema de archivos. Cada carpeta tiene una casilla de verificación para seleccionar la carpeta actual. El proceso de selección lleva algo de tiempo, así que, mientras se ejecuta la operación, hay un botón que está desactivado y al final de la operación estoy habilitando el botón.

Mi problema es que cuando el botón se "desactiva", lo veo de inmediato. Sin embargo, cuando el botón vuelve al modo activado, debo hacer algo (como hacer clic con el mouse) para ver el botón habilitado.

¿Cómo puedo asegurarme de que la interfaz de usuario se actualizará inmediatamente después de habilitar el botón?

Estos son mis botones:

<Button Content="&lt;- 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}" /> 

En mi modelo de vista He añadido este código:

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"); 
     } 
    } 
} 

actualización La interfaz de usuario ocurre justo después de ejecutar un clic del ratón o cualquier pulsación de tecla.

Este es el código de la acción que se Desactivación y activación de los botones:

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; 
} 

¿Qué puedo hacer yo?

+1

tratan this.UpdateLayout() o ButtonsParent.UpdateLayout() –

+0

Cuando la operación se hace estás elevando el evento 'OnPropertyChanged' para sus propiedades interesadas responsables de habilitar/deshabilitar el botón? –

+0

Cuando lo hice, estoy cambiando la propiedad habilitada, pero Set {...} y Set {} incluyen el evento OnPropertyChanged. Cuando intento depurar, todo funciona a la perfección y el botón se habilita sin hacer clic. Puedo resolver cuál es el problema – Ofir

Respuesta

5

Se puede ajustar en su mando a Binding mode TwoWay y definir triggers with PropertyChanged

{Binding ElementName=.., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} 
+0

Lo hice pero el problema todavía existe. – Ofir

+0

El modelo MVVM debe implementar INotifyPropertyChanged, para poder enviar notificaciones a los controles –

+0

Ya lo implementé – Ofir

1

Aquí está un ejemplo de código de cómo puede configurar su modelo de vista con el método INotifyPropertyChanged de envío de mensajes para actualizar la interfaz de usuario:

public class MyViewModel : INotifyPropertyChanged 
{ 
    /******************************************************/ 
    /* Property that you have created two-way binding for */ 
    /******************************************************/ 
    private double _myProperty 
    public double MyProperty 
    { 
     get { return _myProperty; } 
     set 
     { 
      _myProperty = value; 

      OnNotifyPropertyChanged("MyProperty"); 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnNotifyPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #endregion INotifyPropertyChanged Members 
} 
+1

Hola, Mi proyecto ya contiene este código. – Ofir

+0

Asegúrese de que el valor de OnNotifyPropertyChanged ("MyProperty"); es correcto. –

1

OK Encontré una solución.
He intentado todo sin éxito y, finalmente, me encontré con este tema: Refresh WPF Command

he utilizado CommandManager.InvalidateRequerySuggested()

y sus obras.

Gracias por su ayuda

Cuestiones relacionadas