Home > Enterprise >  System.Windows.Data Error: 5 ; FontSizeConverter is causing Problems
System.Windows.Data Error: 5 ; FontSizeConverter is causing Problems

Time:12-23

I am struggling with this Error N°5. Here is the complete Error Message:

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='0' BindingExpression:Path=ActualHeight; DataItem='Grid' (Name='gridEingabemaske'); target element is 'TextBox' (Name='txtabmessungStecknuss'); target property is 'FontSize' (type 'Double')

Here is what I have figured out so far: I have a WPF-Control, which hosts a lot of Textboxes (118 to be specific). I also use a FontSizeConverter to manipulate the FontSize in the Textboxes. This FontSizeConverter seems to cause the Problem, because it expects a Double-Value but gets a 0 (Integer) instead.

How can I fix this?

my xaml-code (just give you 1 of 118 Textboxes at the End):

<UserControl x:Class="SchrauberDB.Controls.Eingabemaske"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:SchrauberDB.View"
         xmlns:dm="clr-namespace:SchrauberDB.DataModel"
         mc:Ignorable="d" 
         d:DesignHeight="250" d:DesignWidth="1100"
         FontFamily="Arial">

<UserControl.Resources>

    <dm:FontSizeConverter x:Key="fontSizeCon" />

    <Style TargetType="{x:Type Grid}">
        <Style.Resources>
            <Style TargetType="{x:Type Border}">
                <Setter Property="CornerRadius" Value="50"/>

            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type StackPanel}">
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="Margin" Value="20,0,0 ,0" />
        <Style.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="FontSize" Value="18" />

                <Setter Property="FontFamily" Value="Arial" />
                <Setter Property="FontWeight" Value="Medium" />
            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type TextBox}">
        <Style.Resources>
            <Style TargetType="{x:Type Border}">
                <Setter Property="CornerRadius" Value="5"/>
                <Setter Property="BorderBrush" Value="#6A767D" />
            </Style>
        </Style.Resources>
        <Setter Property="Width" Value="160" />
        <Setter Property="Height" Value="30" />
        <Setter Property="BorderBrush" Value="#6A767D" />
        <Setter Property="Background" Value="#C2CACF" />

    </Style>
</UserControl.Resources>

<Grid x:Name="gridEingabemaske" Background="#FEFFFF" >

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="400"/>
        <ColumnDefinition />
        <ColumnDefinition Width="200"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Button Grid.Column="3" Grid.Row="0" 
            Height="45" Width="160">
        <TextBlock FontSize="14" FontWeight="Medium">
            Speichern
        </TextBlock>
    </Button>
    <Button Grid.Column="3" Grid.Row="1" 
            Height="45" Width="160" Click="Button_CreateBemi_Click" 
            >
        <TextBlock  FontSize="14" FontWeight="Medium">
            Neues Bemi Anlegen
        </TextBlock>
    </Button>

    <ListView x:Name="lvEingabe" Margin="25" Grid.RowSpan="2">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

    <StackPanel x:Name="abmessungStecknuss" Visibility="Hidden">
        <TextBlock>Abmessung Stecknuss</TextBlock>
        <TextBox x:Name="txtabmessungStecknuss" Text="{Binding Path=abmessungStecknuss}" KeyDown="OnKeyDownHandler" FontSize="{Binding Path=ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}, Converter={StaticResource fontSizeCon}}"></TextBox>
    </StackPanel>
    
    ...

And here´s my FontSizeConverter Class:

namespace SchrauberDB.DataModel
{
    public class FontSizeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double actualHeight = System.Convert.ToDouble(value);
            int fontSize = (int)(actualHeight * .05);
            return fontSize;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

CodePudding user response:

The exception statement

[...] target property is 'FontSize' (type 'Double')

tells you that an int is not the valid type here. Instead you should return a double in your Convert method:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    double actualHeight = System.Convert.ToDouble(value);
    double fontSize = actualHeight * .05;
    return fontSize;
}

CodePudding user response:

The cast from double to int is redundant. You should remove it. Furthermore, don't throw a NotImplementedException exception. If the ConvertBack method is not supported, then throw the NotSupportedException.

The problem here is that, according to the error message, the value for the ActualHeight is 0. While 0 is a valid height, it is an illegal value for the FontSize.

The message:

"Value produced by BindingExpression is not valid for target"
Then it states that the value is
"Value='0'"
The target is
"target element is 'TextBox'"
The target property
"target property is 'FontSize'"

The message is clealy communicating an invalid value and not an invalid type!
The error message translates to: "The value 0 is not valid for the TextBox.FontSize property."

Equipped with this knowledge, you now consult the API reference for the Control.FontSize property. From here you learn:

The font size must be a positive number.

From our Math class we know that zero is not a positive number.
Problem identified. Solution is obvious: prevent illegal converter values.

This means, you should add some robustness to your converter implementation:

public class FontSizeConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    double actualHeight = System.Convert.ToDouble(value);
    double fontSize = actualHeight * .05;
    return Math.Max(0.1, fontSize);

    // Alternatively return a default value e.g., 12
    return fontsize == 0 ? 12 : fontsize
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotSupportedException();
  }
}
  • Related