MultiBinding - 指定的转换无效
MultiBinding - Specified Cast Is Not Valid
下面的代码绑定了列宽:Samp1.ActualWidth
和 Samp2.ActualWidth
到 StatName.Width
。参见:Bind DataGrid Column Width to Two Colums of Another DataGrid
然而,Designer 报错Specified cast is not valid.
,但尽管有错误,代码仍然按预期编译和执行。
即使它按预期运行,"error" 仍然困扰着我。
问题: 错误原因:Specified cast is not valid.
?什么被投射到什么?我该如何解决?如果修复不是直接的,我怎样才能至少隐藏或忽略错误?
注:题目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; }
}
在任何转换器中,您应该始终期望一个(或多个)值可以是 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
)。
下面的代码绑定了列宽:Samp1.ActualWidth
和 Samp2.ActualWidth
到 StatName.Width
。参见:Bind DataGrid Column Width to Two Colums of Another DataGrid
然而,Designer 报错Specified cast is not valid.
,但尽管有错误,代码仍然按预期编译和执行。
即使它按预期运行,"error" 仍然困扰着我。
问题: 错误原因:Specified cast is not valid.
?什么被投射到什么?我该如何解决?如果修复不是直接的,我怎样才能至少隐藏或忽略错误?
注:题目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; }
}
在任何转换器中,您应该始终期望一个(或多个)值可以是 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
)。