WPF数据网格中的TextWrapping文本框

3
我一直在尝试让我的DataGrid中的文本框自动换行。我已经实现了,但似乎会破坏文本绑定。
XAML
<DataGrid x:Name="dataGrid" Grid.Row="0" AutoGenerateColumns="False" ItemsSource="{Binding}">
    <!-- <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <TextBox TextWrapping="Wrap" Text="{Binding Path=Value}">
                        </TextBox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.CellStyle> -->
</DataGrid>

我使用类似于数据集的方式添加列和行。
CS
    #region Variables
    private DataTable m_stringData = new DataTable();
    private DataSet m_stringDataSet = new DataSet();
    #endregion

    #region Constructors
    public LocEditor()
    {
        InitializeComponent();

        AddColumn("ID", 100);
        AddString("Test");
        dataGrid.DataContext = m_stringData;
    }
    #endregion

    #region Methods

    private void AddColumn(string l_columnName, int l_iWidth)
    {
        m_stringData.Columns.Add(l_columnName, typeof(string));

        dataGrid.Columns.Add(new DataGridTextColumn
        {
            Header = l_columnName,
            Width = l_iWidth,
            Binding = new Binding(l_columnName)
            //Binding = new Binding(string.Format("[{0}]", l_columnName))
        });
    }

    private void AddString(string l_stringID)
    {
        m_stringData.Rows.Add();
        m_stringData.Rows[m_stringData.Rows.Count - 1][0] = l_stringID;
    }

    #endregion

任何帮助都将不胜感激。
3个回答

2
我弄清了。通过设置Element和EditingElementStyle,我不必重置Binding。
DataGridTextColumn l_column = new DataGridTextColumn();
l_column.Header = l_columnName;
l_column.Binding = new Binding(l_columnName);
l_column.Width = l_iWidth;

Style l_textStyle = new Style(typeof(TextBlock));
l_textStyle.Setters.Add(new Setter(TextBlock.TextWrappingProperty, TextWrapping.Wrap));
l_column.ElementStyle = l_textStyle;
Style l_textEditStyle = new Style(typeof(TextBox));
l_textEditStyle.Setters.Add(new Setter(TextBox.TextWrappingProperty, TextWrapping.Wrap));
l_column.EditingElementStyle = l_textEditStyle;

dataGrid.Columns.Add(l_column);

1

这将GridViewColumn直接插入到GridView中,但对我而言有效。

<ListView Name="myListView">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="HEADER NAME" x:Name="header">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox TextWrapping="Wrap" Text="{Binding Path=Value}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

为了完整地看到包装后的文本,您需要将行高设置足够大以查看它(或动态进行高度转换)。
<My:ToHeightConverter x:Key="heightConverter" />

<Style TargetType="ListViewItem">
    <Setter Property="Height" Value="{Binding ElementName=myListView, Path=ActualHeight, Converter={StaticResource heightConverter}}" />
</Style>

然后在 GridView 的代码后台:

[ValueConversion(typeof(double), typeof(double))]
public class ToHeightConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        return (((double)value * 10);      //return the height wanted here
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        throw new NotImplementedException();
    }
}

问题是我不知道最终会有多少列。因此,我的 DataTable 必须为我完成这项工作。我不能在 XAML 中静态创建我的列。谢谢。 - jfmajor

0
如果您想要在DataGrid中的所有TextBoxes上添加TextWrapping,我建议您在DataGrid.Resources中为它们创建一个隐式样式。
<DataGrid.Resources>
    <Style TargetType="{x:Type TextBox}">
        <Setter Property="TextWrapping" Value="Wrap" />
    </Style>
</DataGrid.Resources>

数据未在您的模板中显示的原因是因为您缺少ContentPresenter。这是显示实际DataGridCell呈现内容的对象。DataGridCell本身不知道其单元格内容是什么,因此不知道绑定是什么。
例如,这样可以正常工作。
<Style TargetType="DataGridCell">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <TextBlock TextWrapping="Wrap">
                    <ContentPresenter Content="{TemplateBinding Content}" />
                </TextBlock>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

但不是这个

<Style TargetType="DataGridCell">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <TextBox TextWrapping="Wrap" Text="{TemplateBinding Content}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

因为 Content 是在单元格中的任何对象,无论是 TextBoxTextBlockComboBox 等等。


1
谢谢回复!如果我只添加资源部分,我的文本框似乎不会受到影响。至少我没有注意到任何变化。使用样式时,我收到“在使用ItemsSource之前,项集合必须为空”的错误提示。我错过了什么?再次感谢。 - jfmajor
1
好的,我缺少一些XAML标记。但是仍然没有文本换行。当我选择单元格时,文本会消失。 - jfmajor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接