XAML: la visibilidad basada en el ancho real se comporta de forma extraña en una cuadrícula

usuario2921009

Estoy tratando de entender cómo vincular la visibilidad de los elementos secundarios al tamaño de su elemento principal. Mi estrategia fue construir un convertidor que tenga un valor de umbral int (que corresponderá con el ancho de un control principal), y en base a ese valor de umbral, decide si un elemento secundario debe ser visible o no:

public class IntToVisibilityConverter : IValueConverter
{
    public IntToVisibilityConverter()
    {
        FalseVisibility = Visibility.Collapsed;
        Negate = false;
        VisibilityThreshold = 0;
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int iVal;
        bool result = int.TryParse(value.ToString(), out iVal);
        if (!result) return value;
        bool isVisible;

        if (iVal < VisibilityThreshold)
        {
            isVisible = false;
        }
        else
        {
            isVisible = true;
        }

        isVisible = Negate ? !isVisible : isVisible;

        if (isVisible)
        {
            return Visibility.Visible;
        }
        else
        {
            return FalseVisibility;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Visibility? val = null;
        if (value is Visibility) val = (Visibility)value;

        if (!val.HasValue) return value;

        bool result = val == Visibility.Visible;

        result = Negate ? !result : result;

        if (result)
        {
            return VisibilityThreshold;
        }
        else
        {
            return VisibilityThreshold - 1;
        }
    }

    public bool Negate { get; set; }
    public int VisibilityThreshold { get; set; }
    public Visibility FalseVisibility { get; set; }
}

Para probar cómo funciona, construí una interfaz de usuario muy simple que se ve así:

<Window.Resources>
    <ResourceDictionary>
        <local:IntToVisibilityConverter x:Key="IntConverter" VisibilityThreshold="600" Negate="True" />
    </ResourceDictionary>
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Button Grid.Column="1" x:Name="button1">
        <Ellipse Fill="Orange" Width="100" Height="100" Visibility="{Binding ElementName=button1, Path=ActualWidth, Converter={StaticResource IntConverter}}" />
    </Button>
</Grid>

Esto funciona bien sin problemas: cuando estiro la ventana y el botón alcanza un cierto ancho, la elipse desaparece y reaparece cuando contrasta la ventana.

Sin embargo, me encuentro con un comportamiento extraño una vez que agrego otra columna a la cuadrícula como esta:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Button Grid.Column="1" x:Name="button1">
        <Ellipse Fill="Orange" Width="100" Height="100" Visibility="{Binding ElementName=button1, Path=ActualWidth, Converter={StaticResource IntConverter}}" />
    </Button>
    <Button Grid.Column="2" x:Name="button2">
        <Ellipse Fill="DarkOrange" Width="100" Height="100" Visibility="{Binding ElementName=button2, Path=ActualWidth, Converter={StaticResource IntConverter}}" />
    </Button>
</Grid>

Ahora, cuando ejecuto esta aplicación, si abro la ventana de modo que el ancho de los botones pase el umbral, en lugar de desaparecer las elipses, comienzan a parpadear. Es como si con cada cambio de ancho simplemente cambiaran su visibilidad hacia adelante y hacia atrás en lugar de colapsar permanentemente.

¿Alguien puede explicar por qué está haciendo eso y cómo podría hacer que funcione sin sorpresas?

Gracias.

Peter Duniho

El error principal es que su convertidor está tratando de hacer los cálculos matemáticos intaunque todas las métricas de dimensión en WPF lo son double. Incluso en el ejemplo supuestamente "funcional", la elipse solo desaparecerá cuando el ancho de la ventana sea un número entero exacto. De lo contrario, el convertidor falla en el TryParse()método y luego devuelve lo que es para la Visibilitypropiedad un valor sin sentido completo (es decir, el doubleque se le pasó originalmente).

Cambié su convertidor para que se vea así y ambos ejemplos ahora funcionan perfectamente para mí:

public class IntToVisibilityConverter : IValueConverter
{
    public IntToVisibilityConverter()
    {
        FalseVisibility = Visibility.Collapsed;
        Negate = false;
        VisibilityThreshold = 0;
    }

    public object Convert(object valueObject, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double value = (double)valueObject;
        bool isVisible;

        if (value < VisibilityThreshold)
        {
            isVisible = false;
        }
        else
        {
            isVisible = true;
        }

        isVisible = Negate ? !isVisible : isVisible;

        if (isVisible)
        {
            //System.Diagnostics.Debug.WriteLine("isVisible");
            return Visibility.Visible;
        }
        else
        {
            //System.Diagnostics.Debug.WriteLine("NOT isVisible");
            return FalseVisibility;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Visibility? val = null;
        if (value is Visibility) val = (Visibility)value;

        if (!val.HasValue) return value;

        bool result = val == Visibility.Visible;

        result = Negate ? !result : result;

        if (result)
        {
            return VisibilityThreshold;
        }
        else
        {
            return VisibilityThreshold - 1;
        }
    }

    public bool Negate { get; set; }
    public double VisibilityThreshold { get; set; }
    public Visibility FalseVisibility { get; set; }
}

Si lo desea, puede realizar una comprobación adicional del valueObjectparámetro y regresar Binding.DoNothingsi valueObject is doublefalla. En mi humilde opinión, es innecesario, pero evitará que el convertidor arroje una excepción momentáneamente durante la inicialización en caso de que obtenga algo DependencyProperty.UnsetValuecomo el valor por alguna razón.

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

Problema extraño con la configuración de la visibilidad contraída en la cuadrícula (c #, xaml, UWP)

El enlace de visibilidad en la cuadrícula no funciona

Establezca el ancho de la primera columna igual al ancho de la cuadrícula menos la segunda columna en xaml

Chrome se comporta de forma extraña en el modo bootstrap

La matriz ruby se comporta de forma extraña en el controlador de rieles

Establecer el ancho de la cuadrícula en automático

XAML: haga que el tamaño del botón se ajuste a la cuadrícula en lugar del ancho del texto

¿Cómo centro el título de una columna de la cuadrícula en xaml?

Limitar el ancho de una columna al ancho de un elemento de cuadrícula en particular

Limitar el ancho de una columna al ancho de un elemento de cuadrícula en particular

Establecer el valor de la fecha en una cuadrícula interactiva basada en un elemento de página

¿Cómo implementar la visibilidad basada en atributos de las columnas de la cuadrícula de Kendo?

getElementsByClassName se comporta de forma extraña en el script de contenido de la extensión de Chrome

Pycharm se comporta de forma extraña con Git (el nombre de archivo en la entrada del árbol contiene barra invertida)

¿Cómo calcular el ancho de una columna de cuadrícula CSS en IE11 para la animación?

¿Cómo calcular el ancho de una columna de cuadrícula CSS en IE11 para la animación?

El texto de la etiqueta no se ajusta en una configuración de cuadrícula de Bootstrap

EditText se comporta de forma extraña en el cambio de orientación

La red se entrena bien en una cuadrícula de forma N, pero cuando se evalúa cualquier variación falla

Kendo angular: establezca el ancho de la columna de la cuadrícula en CSS o SCSS

la directiva funciona de forma extraña en la cuadrícula de arranque

Python: trazar una cuadrícula de color basada en valores

Construya una cuadrícula basada en dos vectores de entrada

dibujar una cuadrícula de color basada en la densidad de puntos usando python matplotlib

¿El ancho de columna compatible con bootstrap es igual a cero para ocultar la columna de la cuadrícula en pantallas extra pequeñas?

¿Hay alguna manera de especificar el ancho de columna de la cuadrícula en porcentaje?

Establecer el ancho mínimo de la columna en la cuadrícula

Establecer el ancho de las columnas en la vista de cuadrícula creada dinámicamente

ancho de las celdas en la tabla de cuadrícula

TOP Lista

CalienteEtiquetas

Archivo