【问题标题】:WPF Toolkit DataGridTextColumn with scrollbar带有滚动条的 WPF 工具包 DataGridTextColumn
【发布时间】:2014-08-28 08:12:01
【问题描述】:

我设计了一个项目,该项目具有用户定义的数据网格控件。控件的数据网格的某些列是具有双向绑定的 DataGridTextColumn(从/向绑定模型读取和写入数据)。 DataGridTextColumn 的某些单元格包含很长的文本,无法在单元格中成功显示。我决定在这个单元格中放置滚动条。每个单元格列都包含一些用户定义的样式,因此我使用 DataGridCell 模板替换创建了自己的样式。 这里是:

<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 Nested binding in a controltemplate)但没有任何效果...

附:我无法将 datagridtext 列更改为 datatemplate textcolumn,因为控件存储在外部 dll 库中。

提前致谢。

【问题讨论】:

  • 也许您需要为单元格模板和单元格编辑模板定义两个单独的模板。对两者使用相同可能会导致此类问题。您能否分享更多有关如何使用此模板的代码,我们会尝试为您提供一些解决方案。
  • 我将此样式与链接到 datagridtextcolumn cellstyle 属性的默认样式合并。你能告诉我单元格模板和单元格编辑模板的模板示例吗?
  • 我只有这个代码
  • 您使用的是哪个版本的WPF Toolkit
  • .Net 3.5 版本

标签: c# wpf datagrid datatemplate datagridcell


【解决方案1】:

这是解决问题的方法

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

但由于没有明确的编辑模式,这种方法可能会导致数据不一致。

【讨论】:

  • 感谢您的回复。它可以工作,但是当单元格不编辑时没有滚动条,所以,我只会在编辑模式下看到所有文本。但是我项目中的一些网格是只读的。为什么我问有关为单元格的所有模式(编辑和不编辑)进行滚动的问题。
  • 我的示例版本做了我想要的,但不要更新 dinded 模型
  • 这确实可以通过以你的方式进行诱惑。因此,将您的模板与带有文本块的滚动查看器一起使用,并使用答案中的编辑样式,这将带来两个好处。
  • 好的,但也许可以通过触发“IsEditing”属性更改时执行的控件模板或更改模板进行双向绑定?
  • 整个问题是绑定,否则你有一个体面的解决方案来满足你的需求。我认为可以解决这个问题,让我们看看我们如何做到这一点。
【解决方案2】:

答案很简单。感谢在这里How to use TwoWay binding from within a UserControl?WPF TemplateBinding vs RelativeSource TemplatedParent给出答案的人

下一个代码解决了我的问题:

<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>

它可以满足我的所有需求。

附:感谢大家的回复。

【讨论】:

  • 但单元格必须具有 IsReadOnly="True" 属性,我认为这很奇怪......
猜你喜欢
  • 2011-06-17
  • 1970-01-01
  • 2011-01-02
  • 1970-01-01
  • 2016-08-02
  • 2020-07-18
  • 2016-06-26
  • 2010-12-17
  • 2021-12-13
相关资源
最近更新 更多