带有滚动条的WPF Toolkit DataGridTextColumn
本文关键字:Toolkit DataGridTextColumn WPF 滚动条 | 更新日期: 2023-09-27 18:19:38
我设计了一个项目,该项目具有带有数据网格的用户定义控件。控件数据网格的某些列是具有双向绑定的DataGridTextColumn(用于从绑定模型读取数据和向绑定模型写入数据)。DataGridTextColumn的某些单元格包含很长的文本,无法在单元格中成功显示。我决定在这些单元格中放置滚动条。每个单元格列都包含一些用户定义的样式,所以我用DataGridCell模板replacment创建了自己的样式。这是:
<Style x:Key="DataGridTextColumnWithScrollBar" TargetType="{x:Type Control}" BasedOn="{StaticResource {x:Type wpf_toolkit:DataGridCell}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control}">
<ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Mode=TwoWay}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Text, Mode=TwoWay}"
TextWrapping="Wrap" VerticalScrollBarVisibility="Auto"
VerticalAlignment="Stretch" Margin="2,0" BorderThickness="0"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
样式DataGridTextColumnWithScrollBar与基本数据网格文本列单元格样式合并。它工作正常,但我不能编辑文本(所有滚动显示,但在编辑文本后,模型不会更新)。有什么解决方案可以解决我的问题吗?我尝试了很多方法(例如,在控制模板中的WPF嵌套绑定),但都不起作用。。。
附言:我无法将datagridtext列更改为datatemplate textcolumn,因为控件存储在外部dll库中。
提前谢谢。
以下是如何解决问题
样式,请注意,我已经删除了模板,此样式针对TextBox
<Style x:Key="DataGridTextColumnWithScrollBar"
TargetType="{x:Type TextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="VerticalScrollBarVisibility"
Value="auto" />
<Setter Property="TextWrapping"
Value="Wrap" />
<Setter Property="VerticalAlignment"
Value="Stretch" />
<Setter Property="Margin"
Value="2,0" />
<Setter Property="BorderThickness"
Value="0" />
</Style>
然后使用,而不是CellStyle
使用EditingElementStyle
<wpf_toolkit:DataGridTextColumn Header="Some long text 2"
Binding="{Binding SomeLongText1, Mode=TwoWay}"
EditingElementStyle="{StaticResource DataGridTextColumnWithScrollBar}" />
如果你也想设置普通视图的样式,那么添加以下样式
<Style x:Key="DataGridTextBlockColumnWithWrap"
TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="TextWrapping"
Value="Wrap" />
<Setter Property="VerticalAlignment"
Value="Stretch" />
<Setter Property="Margin"
Value="2,0" />
</Style>
使用
<wpf_toolkit:DataGridTextColumn Header="Some long text 2"
Binding="{Binding SomeLongText1, Mode=TwoWay}"
EditingElementStyle="{StaticResource DataGridTextColumnWithScrollBar}"
ElementStyle="{StaticResource DataGridTextBlockColumnWithWrap}" />
您可以使用模板为非编辑模式以及添加滚动条
编辑
这里讨论的是一种基于触发器的显式绑定风格
<Style x:Key="DataGridTextColumnWithScrollBar"
TargetType="{x:Type wpf_toolkit:DataGridCell}"
BasedOn="{StaticResource {x:Type wpf_toolkit:DataGridCell}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpf_toolkit:DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ScrollViewer VerticalScrollBarVisibility="Auto"
x:Name="view">
<TextBlock Text="{Binding SomeLongText1}"
TextWrapping="Wrap" />
</ScrollViewer>
<TextBox Text="{Binding SomeLongText1}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto"
VerticalAlignment="Stretch"
Margin="2,0"
BorderThickness="0"
x:Name="edit"
Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEditing"
Value="True">
<Setter Property="Visibility"
TargetName="view"
Value="Collapsed" />
<Setter Property="Visibility"
TargetName="edit"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
您可以看到正在使用显式绑定,因此需要为每一列创建样式。用法保持不变,但由于这是一个进入编辑模式的自定义模板,您可能需要按F2
或者直截了当地说,你可以使用
<Style x:Key="DataGridTextColumnWithScrollBar"
TargetType="{x:Type wpf_toolkit:DataGridCell}"
BasedOn="{StaticResource {x:Type wpf_toolkit:DataGridCell}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpf_toolkit:DataGridCell}">
<TextBox Text="{Binding SomeLongText1}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto"
VerticalAlignment="Stretch"
Margin="2,0"
BorderThickness="0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但由于没有明确的编辑模式,这种方法可能导致数据不一致。
答案很简单。感谢在这里给出答案的人如何在UserControl中使用TwoWay绑定?这里是WPF TemplateBinding与RelativeSource TemplateParent
我的问题通过下一个代码解决:
<Style x:Key="DataGridTextColumnWithScrollBar" TargetType="{x:Type wpf_toolkit:DataGridCell}"
BasedOn="{StaticResource {x:Type wpf_toolkit:DataGridCell}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpf_toolkit:DataGridCell}">
<TextBox Name="txtBox" Text="{Binding Content.Text,
RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
VerticalScrollBarVisibility="Auto" TextWrapping="Wrap"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
所以我可以这样使用它:
<wpf_toolkit:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items, Mode=TwoWay}"
RowStyle="{StaticResource DataGridRowMaxHeihgt }" ColumnWidth="*"
IsReadOnly="True">
<wpf_toolkit:DataGrid.Columns>
<wpf_toolkit:DataGridTextColumn Header="Some long text 2" IsReadOnly="True"
Binding="{Binding SomeLongText1, Mode=TwoWay}"
CellStyle="{StaticResource DataGridTextColumnWithScrollBar}"/>
<wpf_toolkit:DataGridTextColumn Header="Some long text 2"
Binding="{Binding SomeLongText2, Mode=TwoWay}" IsReadOnly="False"
CellStyle="{StaticResource DataGridTextColumnWithScrollBar}"/>
</wpf_toolkit:DataGrid.Columns>
</wpf_toolkit:DataGrid>
它成就了我想要的一切。
附言:感谢大家的回复。