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

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

我正在为这个错误 N°5 苦苦挣扎。这是完整的错误消息:

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')

以下是我目前的了解: 我有一个 WPF-Control,它承载了很多文本框(具体来说是 118 个)。我还使用 FontSizeConverter 来操作文本框中的 FontSize。这个 FontSizeConverter 似乎是导致问题的原因,因为它需要一个 Double-Value 但得到的却是 0(整数)。

我该如何解决这个问题?

我的 xaml-代码(最后只给你 118 个文本框中的 1 个):

<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>
    
    ...

这是我的 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();
        }
    }
}

doubleint 的转换是多余的。你应该删除它。此外,不要抛出 NotImplementedException 异常。如果不支持ConvertBack方法,则抛出NotSupportedException.

这里的问题是,根据错误消息,ActualHeight 的值为 0。虽然 0 是有效高度,但 FontSize.

是非法值

留言:

“BindingExpression 生成的值对目标无效”
然后它指出该值为
“值='0'”
目标是
"目标元素是 'TextBox'"
目标属性
“目标 属性 是 'FontSize'”

该消息清楚地传达了无效的 value 而不是无效的 type!
错误消息转换为:“值 0TextBox.FontSize 属性 无效。”

了解了这些知识后,您现在可以参考 Control.FontSize 属性 的 API 参考资料。从这里你可以了解到:

The font size must be a positive number.

根据数学 class 我们知道零不是正数。
问题已确定。解决方案很明显:防止非法转换器值。

这意味着,您应该为您的转换器实现添加一些稳健性:

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();
  }
}