Errores de enlace al enlazar valores nulos al ancho y alto del control wpf

Nuestro proyecto necesita que enlacemos muchas propiedades del control como Height, Width, MinHeight, Row, Column, rowspan... etc. Al hacerlo, observamos errores vinculantes cuando estos valores son null que obtendremos de DB.

Para ilustrar, mi MainWindow.xaml.cs Se ve como esto.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        //TextWidth  id null
        TextBlockSize1 = new ItemSize() { TextHeight=20 };
        //TextWidth is null
        TextBlockSize2 = new ItemSize() { TextWidth = 40 };
        //TextHeight is null and TextWidth is null
        TextBlockSize3 = new ItemSize() { TextWidth = 40 };
        textblock1.DataContext = TextBlockSize1;
        textblock2.DataContext = TextBlockSize2;
        textblock3.DataContext = TextBlockSize3;
    }
    public ItemSize TextBlockSize1 { get; set; }

    public ItemSize TextBlockSize2 { get; set; }

    public ItemSize TextBlockSize3 { get; set; }
}

public class ItemSize
{
    public double? TextHeight { get; set; }
    public double? TextWidth { get; set; }
}

y MainWindow.xaml Se ve como esto.

<Window x:Class="WPfAppln1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ctrl="clr-namespace:WPfAppln1.Controls"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel >
         <TextBlock Name="textblock1" Text=" TextBlock 1"  Width="{Binding TextWidth}"  Height="{Binding TextHeight}"></TextBlock>
         <TextBlock Name="textblock2" Text=" TextBlock 2"  Width="{Binding TextWidth}"  Height="{Binding TextHeight}"></TextBlock>
         <TextBlock Name="textblock3" Text=" TextBlock 3"  Width="{Binding TextWidth, TargetNullValue=Auto}"  Height="{Binding TextHeight, TargetNullValue=Auto}"></TextBlock>     
   </StackPanel>
</Window>

Los siguientes errores de vinculación se muestran para esto en la viuda de salida:

System.Windows.Data Error: 5 : 'WPfAppln1.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0__b77a5c561934e089\System.Numerics.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=TextWidth; DataItem='ItemSize' (HashCode=43929715); target element is 'TextBlock' (Name='textblock1'); target property is 'Width' (type 'Double')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=TextHeight; DataItem='ItemSize' (HashCode=57104612); target element is 'TextBlock' (Name='textblock2'); target property is 'Height' (type 'Double')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=TextHeight; DataItem='ItemSize' (HashCode=59587750); target element is 'TextBlock' (Name='textblock3'); target property is 'Height' (type 'Double')
    The thread '<No Name>' (0x2c60) has exited with code 0 (0x0).

Y debido a estos errores, la aplicación tarda mucho en cargar las pantallas.

Entonces, la pregunta es cómo acomodar los valores anulables en el enlace a los controles wpf y cómo proporcionar un valor predeterminado como 'auto' para las propiedades de ancho del control cuando el valor enlazado es nulo.

preguntado el 12 de junio de 12 a las 12:06

¿Está seguro de que estos errores de vinculación ralentizan su aplicación? Solo soy curiosidad, porque siempre pensé que los errores de enlace en la ventana de salida no afectan el rendimiento ... -

@SvenG: Sí, estos errores de vinculación pueden causar problemas de rendimiento, personalmente me he enfrentado a esto con DataGrid. Aquí es un enlace de MS que dice: "WPF intenta varias formas diferentes de resolver los errores de ruta, incluida la búsqueda de propiedades adjuntas, y esto es bastante costoso", ver también este -

¡Gracias por la información que es muy útil para mí! -

3 Respuestas

Puedes usar el TargetNullValue(en caso de que la fuente sea nula) o FallbackValue(en caso de que el enlace falle, por ejemplo DataContext is null)

Actualizar:

Gracias Dean por señalar eso, asumí erróneamente que Auto funcionará (es decir TypeConverter se encargará de la conversión).

Pero aún puede usar la propiedad automática y proporcionar Auto valor en XAML usando x:Static Extensión de marcado como esto -

<TextBlock Name="textblock1" Text=" TextBlock 1"  
    Height="{Binding TextHeight, TargetNullValue={x:Static System:Double.NaN}, 
               FallbackValue={x:Static System:Double.NaN}}">
</TextBlock> 

Value="{x:Static System:Double.NaN}" también se puede utilizar en DataTrigger acercarse así -

<TextBlock.Style>
    <Style>
       <Setter Property="Control.Width" Value="{Binding Path=TextWidth}" />
        <Style.Triggers>
            <DataTrigger
               Binding="{Binding Path=TextWidth}"
               Value="{x:Null}">
               <Setter Property="Control.Width" Value="{x:Static System:Double.NaN}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</TextBlock.Style>

Nota: requerirá este espacio de nombres -

xmlns:System="clr-namespace:System;assembly=mscorlib" 

Código antiguo:

<TextBlock Name="textblock1" Text=" TextBlock 1"  Width="{Binding TextWidth}"  
    Height="{Binding TextHeight, TargetNullValue=Auto, FallbackValue=Auto }">
</TextBlock> 

Otra solución puede ser tener un disparador como este:

<TextBlock.Style>
    <Style>
        <Style.Triggers>
            <DataTrigger
                Binding="{Binding Path=TextWidth}"
                Value="{x:Null}">
                <Setter Property="Control.Width" Value="Auto" />
            </DataTrigger>
            <DataTrigger
                Binding="{Binding Path=TextHeight}"
                Value="{x:Null}">
                <Setter Property="Control.Height" Value="Auto" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</TextBlock.Style>

respondido 05 nov., 15:07

-1: no puede usar la cadena 'Auto' como TargetNullValue o FallbackValue para que su solución no funcione - tiza decano

+1 Gracias por TargetNullValue. Solo quería reutilizar un bool anulable en un objetivo bool, así que esto funcionó IsEnabled="{Binding Path=ItemEnabled, Converter={StaticResource negate}, TargetNullValue=false}" - Bob no-muerto

@reasra me alegro de que haya ayudado :) - Akjoshi

La solución más simple (en mi opinión) es no usar propiedades automáticas.

p.ej

private double textHeight = Double.NaN;
public double TextHeight
{
    get { return textHeight; }
    set { textHeight = value; }
}

private double textWidth = Double.NaN;
public double TextWidth
{
    get { return textWidth; }
    set { textWidth = value; }
}

Respondido el 12 de junio de 12 a las 13:06

Utilicé propiedades de dependencia, pero esto funcionó para mí. Esto es lo que obtuve: ¿doble público? Altura { get => (doble)GetValue(HeightProperty); set { if (valor == nulo) Altura = doble.NaN; else SetValue(PropiedadAltura, valor); } } - fénix_rojo

Si tus dos double? las propiedades no tienen por qué ser anulables en absoluto, simplemente puede convertirlas en regulares double propiedades Esto sería predeterminado a 0.

Si eso no es posible, o 0 es un valor predeterminado inaceptable, yo mismo preferiría la solución FallbackValue. Sin embargo, si su valor predeterminado debe ser 'Auto' (como se mencionó anteriormente), no puede configurar 'Auto' como FallbackValue.

El valor predeterminado de Alto y Ancho no es 0; es Doble.NaN. Alto y Ancho admiten la capacidad de ser un valor "Automático" no establecido. Debido a que Height y Width son valores dobles, Double.NaN se usa como un valor especial para representar este comportamiento "Auto". (desde http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width(v=VS.95).aspx)

Si no puede configurar Double.NaN a una FallbackValue (No lo he probado), yo mismo usaría un convertidor. Si el valor objetivo es null, regreso Double.NaN preferiblemente. http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx para obtener más información sobre IValueConverter.

Respondido el 12 de junio de 12 a las 13:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.