2009-04-05 9 views
5

En mi programa tengo tres estados de IU distintos (Normal, Correcto y Error) y en cada uno los controles son visibles/ocultos, habilitados/deshabilitados, los colores cambian, las etiquetas dicen cosas diferentes ... etc. y en mi código subyacente, básicamente quiero poder decir ChangeWindowState (UI.Normal);¿Cuál es la mejor manera de implementar una máquina de estado UI?

Entonces mi pregunta es ¿cuál es la mejor manera de implementar los cambios de control para cada estado?

Por supuesto que podría cambiar manualmente los controles en el código subyacente, pero me pregunto si tal vez haya una mejor manera de usar temas o estilos wpf. Entonces tal vez podría simplemente configurar la ventana para usar el tema "Error", que he predefinido. Realmente no los entiendo en este momento, así que podría estar usando la terminología equivocada, pero agradecería que alguien me señale la mejor manera de hacer algo como esto.

Gracias!

Respuesta

5

Hay muchas formas de abordar esto, por supuesto. Si tuviera un "modelo de objeto" de estado de programa, podría usar alguna combinación de DataTemplates y DataTriggers. Asumiendo que este no es el caso, aquí hay otro enfoque: Usted ha hecho referencia a una ventana, por lo que suponga que define una "propiedad de dependencia" en su clase de la ventana como esta:

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     this.InitializeComponent(); 

     // Insert code required on object creation below this point. 
    } 

    public ProgramStatus ProgramStatus 
    { 
     get { return (ProgramStatus)GetValue(ProgramStatusProperty); } 
     set { SetValue(ProgramStatusProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for ProgramStatus. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty ProgramStatusProperty = 
     DependencyProperty.Register("ProgramStatus", typeof(ProgramStatus), typeof(Window1), new UIPropertyMetadata(null)); 
} 

public enum ProgramStatus 
{ 
    Normal, 
    Success, 
    Error 
} 

Ahora puede cambiar casi cualquier propiedad de cualquier elemento de la ventana (incluida la ventana en sí), ya sea mediante enlace directo o un desencadenador. He aquí un ejemplo de cambio de color de fondo de la ventana a través de un desencadenador de propiedad:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:l="clr-namespace:Test" 
    x:Class="Test.Window1" 
    x:Name="Window" 
    Title="Window1" 
    Width="640" Height="480"> 
    <Window.Style> 
     <Style TargetType="{x:Type l:Window1}"> 
      <Style.Triggers> 
       <Trigger Property="ProgramStatus"> 
        <Trigger.Value> 
         <l:ProgramStatus>Error</l:ProgramStatus> 
        </Trigger.Value> 
        <Setter Property="Background" Value="Red" /> 
       </Trigger> 
       <Trigger Property="ProgramStatus"> 
        <Trigger.Value> 
         <l:ProgramStatus>Normal</l:ProgramStatus> 
        </Trigger.Value> 
        <Setter Property="Background" Value="Blue" /> 
       </Trigger> 
       <Trigger Property="ProgramStatus"> 
        <Trigger.Value> 
         <l:ProgramStatus>Success</l:ProgramStatus> 
        </Trigger.Value> 
        <Setter Property="Background" Value="Green" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Window.Style> 
    <Grid x:Name="LayoutRoot"/> 
</Window> 
1

Para este tipo de cosas, casi siempre he hecho una función "UpdateUI()". Esta función analiza el estado del modelo/propiedades/estado del miembro y habilita/deshabilita, oculta/muestra, lo que sea. Tratar de difundir este código siempre lleva a un problema (por lo que "ChangeWindowsState (..)" realmente solo establece una propiedad y luego llama a "UpdateUI()").

He visto algunos intentos de manejar esto de forma genérica ... pero ninguno que realmente me haya gustado (por ejemplo, las cosas de WTL). En general, estos no están mal implementados ... pero es fácil exceder rápidamente lo que pueden hacer. Y, en general, la lógica de estado es lo suficientemente importante como para tenerlo codificado explícitamente con una lógica de estilo simple if/then/else que genera menos confusión (mantenimiento, depuración, etc.).

Cuestiones relacionadas