WPF - La mejor manera de responder a los cambios en un modelo de vista en Página / nivel de ventana

StackOverflow https://stackoverflow.com/questions/666784

  •  21-08-2019
  •  | 
  •  

Pregunta

Estoy desarrollando una XBAP y tengo un simple requisito.

El DataContext de toda la página principal está establecida en una instancia de mi UserViewModel. El DependencyProperty tiene una AuthenticationState llamado Authenticated que es una enumeración con valores como 'NotAutheticated', 'AuthenticationFailed' y '<=>'.

Ahora, tengo que responder a cualquier cambio en este valor al ocultar / mostrar diversos elementos en la página.

¿Qué (y dónde) es la mejor manera de hacer eso?

¿Fue útil?

Solución 4

administrado a solucionar el problema utilizando estilos. Es un dolor, pero funciona!

La fuente completo está por debajo.

<Grid x:Name="contentGrid" Grid.Row="1">
        <!--login-->
        <controls:LoginControl>
            <controls:LoginControl.Style>
                <Style>
                    <Setter Property="Control.Opacity" Value="0"/>
                    <Setter Property="Control.IsHitTestVisible" Value="False"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Source={StaticResource UserViewModel},Path=UserAuthenticationState}"
                                     Value="{x:Static model:AuthenticationState.NotAuthenticated}">
                            <Setter Property="Control.IsHitTestVisible" Value="True"/>
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation To="1" Duration="0:0:2"
                                                         Storyboard.TargetProperty="Opacity"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation To="0" Duration="0:0:2"
                                                         Storyboard.TargetProperty="Opacity"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </controls:LoginControl.Style>
        </controls:LoginControl>    

        <!--slider-->
        <slider:PageSlider>
            <Button>1</Button>
            <Button>2</Button>
            <Button>3</Button>
            <slider:PageSlider.Style>
                <Style>
                    <Setter Property="Control.Opacity" Value="0"/>
                    <Setter Property="Control.IsHitTestVisible" Value="False"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Source={StaticResource UserViewModel},Path=UserAuthenticationState}"
                                     Value="{x:Static model:AuthenticationState.Authenticated}">
                            <Setter Property="Control.IsHitTestVisible" Value="True"/>
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation To="1" Duration="0:0:2"
                                                         Storyboard.TargetProperty="Opacity"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation To="0" Duration="0:0:2"
                                                         Storyboard.TargetProperty="Opacity"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </slider:PageSlider.Style>
        </slider:PageSlider>
    </Grid>

Otros consejos

Como se ha mencionado que no puede utilizar un DataTrigger directamente en un control. Un trabajo alrededor sería el uso de un estilo en cada control que necesita ser ocultado.

<Grid>
    <Rectangle Fill="Red" />
    <Grid.Style>
        <Style TargetType="Grid">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Test}" Value="true">
                    <Setter Property="Visibility" Value="Collapsed" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
</Grid>

Un método preferible sería utilizar un convertidor llamado "AuthenticationStateToVisibilityConverter" que se utiliza en la unión propiedad Visibilidad del control a la propiedad AuthenticationState del contexto de datos.

La mejor manera sería utilizar un DataTrigger. Hacer algo como esto:

<Window.Triggers>
    <DataTrigger Binding="{Binding AuthenticationState}" Value="NotAuthenticated">
        <Setter TargetName="nameOfControl" Property="Visibility" Value="Collapsed" />
    </DataTrigger>
    ...
    <TextBox x:Name="nameOfControl" />
</Window.Triggers>

Mientras usuario objeto modelo de vista es en el DataContext de la ventana, entonces esto debería funcionar!

En realidad, la mejor manera de hacer esto es exponer las propiedades adecuadas a partir de su modelo de vista. Esto hace que su lógica más centralizado y más fácil de probar. Además, tiene un mejor rendimiento que los convertidores. Es, después de todo, un modelo de vista. Por lo tanto, se debe modelar la vista. Si la vista de las necesidades de una propiedad para contarlo cuando para ocultar / mostrar un panel, añadir un alojamiento como a su modelo de vista.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top