1

我设计了一个项目,该项目具有用户定义的数据网格控件。控件的数据网格的某些列是具有双向绑定的 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 与基本数据网格文本列单元格样式合并。它工作正常,但我无法编辑文本(所有滚动都会出现,但在编辑文本后,模型不会更新)。有什么办法可以解决我的问题吗?我尝试了很多方法(例如,在 controltemplate 中的 WPF 嵌套绑定)但没有任何效果......

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

提前致谢。

4

2 回答 2

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>

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

于 2014-08-28T10:32:38.957 回答
0

The answer was very simple. Thanks for guys that gived answer here How to use TwoWay binding from within a UserControl? and here WPF TemplateBinding vs RelativeSource TemplatedParent

My problem solves by next code:

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

So I can use it like this:

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

It makes all what i want.

P.S. Thanks for everyone for response.

于 2014-08-28T12:41:58.023 回答