【问题标题】:TextWrapping textbox in WPF DataGridWPF DataGrid中的TextWrapping文本框
【发布时间】:2012-02-15 20:07:52
【问题描述】:

我一直在尝试让我的 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

任何帮助将不胜感激。

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    想通了。通过设置 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);
    

    【讨论】:

      【解决方案2】:

      这会将 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 中静态创建列。不过还是谢谢。
      【解决方案3】:

      如果您只想将 TextWrapping 添加到 DataGrid 中的所有 TextBox,我建议您在 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

      【讨论】:

      • 感谢您的回复!如果我只添加资源部分,我的文本框似乎不会受到影响。至少我没有注意到任何变化。我收到“在使用 ItemsSource 之前,项目集合必须为空”。与样式。我错过了什么?再次,非常感谢。
      • 好的,我错过了一些 XAML 标记。虽然仍然没有文字环绕。当我选择单元格时,文本消失。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多