多绑定 - 指定的转换无效

4
下面的代码将列宽 Samp1.ActualWidthSamp2.ActualWidth 绑定到 StatName.Width。参见:Bind DataGrid Column Width to Two Colums of Another DataGrid 然而,设计师报告错误 指定的强制转换无效。 ,但尽管有错误,代码仍按预期编译和执行。
尽管如此,"错误" 仍然让我感到困扰。
问题:是什么导致了错误 指定的强制转换无效。?正在进行什么样的类型转换?我该如何修复它?如果修复不太容易,那么我该如何隐藏或忽略这个错误?
注意:问题 WPF MultiBinding VS designer exception 类似。然而,那段代码会引发运行时异常,而我的代码会引起构建错误并且顺利运行(没有抛出任何异常)。
Xaml:
<Page.Resources>
    <local:WidthConverter x:Key="WidthConverter" />
</Page.Resources>
<!--- ... -->
<DataGrid IsReadOnly="True" HeadersVisibility="Column">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="Samp1" Binding="{Binding a}" Header="S1"  />
        <DataGridTextColumn x:Name="Samp2" Binding="{Binding b}" Header="S2"  />
        <DataGridTextColumn x:Name="Total" Binding="{Binding c}" Header="Tot" />
    </DataGrid.Columns>
    <local:MyGenericRecord a="5000" b="2500" c="7500" />
    <local:MyGenericRecord a="1000" b="1500" c="2500" />
</DataGrid>

<DataGrid IsReadOnly="True" HeadersVisibility="Column">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="StatName"  Binding="{Binding a}" Header="Stat">
            <DataGridTextColumn.Width >
                <!-- ####################################### -->
                <!-- Begin error: Specified cast is invalid. -->
                <MultiBinding Converter="{StaticResource WidthConverter}">
                    <Binding Source="{x:Reference Samp1}" Path="ActualWidth" />
                    <Binding Source="{x:Reference Samp2}" Path="ActualWidth" />
                </MultiBinding>
                <!-- End error -->
                <!-- ###################################### -->
            </DataGridTextColumn.Width>
        </DataGridTextColumn>
        <DataGridTextColumn x:Name="StatValue" Binding="{Binding b}" Header="Val" Width="{Binding ElementName=Total, Path=ActualWidth}" />
    </DataGrid.Columns>
    <local:MyGenericRecord a="Min" b="2500" />
    <local:MyGenericRecord a="Max" b="7500" />
    <local:MyGenericRecord a="Average" b="5000" />
</DataGrid>

转换器:

public class WidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        double totalWidth = 0;

        foreach (double Width in values)
            totalWidth += Width;
        DataGridLength outLen = new DataGridLength(totalWidth);
        return outLen;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return new object[] { DependencyProperty.UnsetValue, DependencyProperty.UnsetValue};
    }
}

public class MyGenericRecord
{
    public string a { get; set; }
    public string b { get; set; }
    public string c { get; set; }
}

4
检查转换器中值数组中项目的类型。很可能其中一些是DependencyProperty.UnsetValue而不是double类型。要进行测试- 将其更改为foreach (double width in values.OfType<double>())。 - Evk
1
我赞同检查 UnsetValue。第一次遇到它是最意外的事情。这也可能是由于你的 ConvertBack 引起的。如果你实际上没有使用它进行转换,通常最好让它抛出一个 NotSupportedException - TyCobb
1个回答

3
在任何转换器中,您应该始终期望值(或值)可能是DependencyProperty.UnsetValue。当wpf无法获取实际值时,将使用此值。最常见的情况是绑定无法解析(例如-您绑定到不存在的属性)。 WPF设计器不会编译整个代码,因此它可能会出现问题,特别是在绑定方面。请注意,null不能替代UnsetValue,因为null可以是有效值。因此,请预期UnsetValue,并尽可能在这种情况下进行有意义的处理。例如:
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    double totalWidth = 0;
    foreach (double Width in values.OfType<double>())
        totalWidth += Width;
    DataGridLength outLen = new DataGridLength(totalWidth);
    return outLen;
}

这将忽略所有不是双精度的值(包括UnsetValue)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接