带有滚动条的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库中。

提前谢谢。

带有滚动条的WPF Toolkit DataGridTextColumn

以下是如何解决问题

样式,请注意,我已经删除了模板,此样式针对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>

它成就了我想要的一切。

附言:感谢大家的回复。