在数据网格中水平滚动时绑定警告
Binding warning when scrolling horizontally in datagrid
在我的 WPF 应用程序中,当我水平滚动 DataGrid 时,Visual Studio 2010 输出打印此警告:
System.Windows.Data Error: 5 : Value produced by BindingExpression is
not valid for target property.; Value='-0.29487179487171'
BindingExpression:Path=CellsPanelHorizontalOffset; DataItem='DataGrid'
(Name=''); target element is 'Button' (Name=''); target property is
'Width' (type 'Double')
我正在寻找数据网格模板定义;异常应该是由 "Button" object:
上的绑定引起的
<Button
Command="{x:Static DataGrid.SelectAllCommand}"
Focusable="false"
Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}"
Visibility="{Binding Path=HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Width="{Binding Path=CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
宽度 属性 是双倍的,就像绑定中的 CellsPanelHorizontalOffset 属性。
我不明白哪里出了问题,你能帮帮我吗?谢谢
您的错误原因从其描述中很清楚:
Value produced by BindingExpression
is not valid for target property.;
Value='-0.29487179487171
' ...
target element is 'Button
'; ...
target property is 'Width
'
因此,数据绑定到Button.Width
的值是-0.29487179487171
,但显然,Width
不能为负数。但是,如果您在那里使用 Converter
永远不会传递负值,那么您只是在隐藏真正的问题,即 CellsPanelHorizontalOffset
一开始就不应该是负数。
我只能假设您在自定义 DataGrid
中使用了一些手动计算,从 DataGridCellsPanel
返回了错误的值。来自 MSDN 上的 DataGrid
Class 页面:
DataGridCellsPanel
: Gets the horizontal offset for the DataGridCellsPanel
.
我遇到了同样的问题。事实证明,在我的情况下,罪魁祸首是将行 header 宽度设置为零。问题是 DG_ScrollViewer 中有一个按钮,其宽度是通过确定其 parent 的宽度来设置的: Button Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}”。这会将按钮的宽度设置为负数,这不是有效宽度。我发现(目前)真正隐藏行 headers 的唯一方法是将行 header 宽度设置为零,然后 re-write ScrollViewer 模板,这将消除错误并允许水平滚动工作。如果您的 app-wide 数据网格设计没有行 header,这是一个很好的解决方案,否则您可能必须为不同的数据网格设置此 xaml。希望这对某人有所帮助。
<Style BasedOn="{StaticResource ControlBaseStyle}" TargetType="{x:Type DataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
>
<ScrollViewer Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
*********** hard code the width of this button *********
<Button x:Name="HijackThisButton"
Width="0"
Focusable="false"
Visibility="Collapsed"
/>
<DataGridColumnHeadersPresenter Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"
/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="1"
Grid.ColumnSpan="2"
CanContentScroll="{TemplateBinding CanContentScroll}"
/>
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Row="1"
Grid.Column="2"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
/>
<Grid Grid.Row="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar Name="PART_HorizontalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
</Style>
在我的 WPF 应用程序中,当我水平滚动 DataGrid 时,Visual Studio 2010 输出打印此警告:
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='-0.29487179487171' BindingExpression:Path=CellsPanelHorizontalOffset; DataItem='DataGrid' (Name=''); target element is 'Button' (Name=''); target property is 'Width' (type 'Double')
我正在寻找数据网格模板定义;异常应该是由 "Button" object:
上的绑定引起的<Button
Command="{x:Static DataGrid.SelectAllCommand}"
Focusable="false"
Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}"
Visibility="{Binding Path=HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Width="{Binding Path=CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
宽度 属性 是双倍的,就像绑定中的 CellsPanelHorizontalOffset 属性。
我不明白哪里出了问题,你能帮帮我吗?谢谢
您的错误原因从其描述中很清楚:
Value produced by
BindingExpression
is not valid for target property.;
Value='-0.29487179487171
' ...
target element is 'Button
'; ...
target property is 'Width
'
因此,数据绑定到Button.Width
的值是-0.29487179487171
,但显然,Width
不能为负数。但是,如果您在那里使用 Converter
永远不会传递负值,那么您只是在隐藏真正的问题,即 CellsPanelHorizontalOffset
一开始就不应该是负数。
我只能假设您在自定义 DataGrid
中使用了一些手动计算,从 DataGridCellsPanel
返回了错误的值。来自 MSDN 上的 DataGrid
Class 页面:
DataGridCellsPanel
: Gets the horizontal offset for theDataGridCellsPanel
.
我遇到了同样的问题。事实证明,在我的情况下,罪魁祸首是将行 header 宽度设置为零。问题是 DG_ScrollViewer 中有一个按钮,其宽度是通过确定其 parent 的宽度来设置的: Button Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}”。这会将按钮的宽度设置为负数,这不是有效宽度。我发现(目前)真正隐藏行 headers 的唯一方法是将行 header 宽度设置为零,然后 re-write ScrollViewer 模板,这将消除错误并允许水平滚动工作。如果您的 app-wide 数据网格设计没有行 header,这是一个很好的解决方案,否则您可能必须为不同的数据网格设置此 xaml。希望这对某人有所帮助。
<Style BasedOn="{StaticResource ControlBaseStyle}" TargetType="{x:Type DataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
>
<ScrollViewer Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
*********** hard code the width of this button *********
<Button x:Name="HijackThisButton"
Width="0"
Focusable="false"
Visibility="Collapsed"
/>
<DataGridColumnHeadersPresenter Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"
/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="1"
Grid.ColumnSpan="2"
CanContentScroll="{TemplateBinding CanContentScroll}"
/>
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Row="1"
Grid.Column="2"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
/>
<Grid Grid.Row="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar Name="PART_HorizontalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
</Style>