Reputation: 83
I've been trying to make my textboxes in my DataGrid wrap. I got it working but it seems to break the Text binding.
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>
I add the columns and rows using a data set like so.
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
Any help would be greatly appreciated.
Upvotes: 3
Views: 4397
Reputation: 83
Figured it out. By setting the Element and EditingElementStyle, I don't have to reset the 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);
Upvotes: 2
Reputation: 132548
If you're looking to just add TextWrapping to all TextBoxes in your DataGrid, I would suggest making an implicit style for them in your DataGrid.Resources
<DataGrid.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGrid.Resources>
The reason why the data isn't showing up in your Template is because you're missing the ContentPresenter
. This is the object that displays the rendered content of the actual DataGridCell
. The DataGridCell
itself has no idea what the content of its cell is, so doesn't know what the binding is.
For example, this works
<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>
But not this
<Style TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox TextWrapping="Wrap" Text="{TemplateBinding Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
because the Content
is whatever object happens to be in the cell at the time, whether it is a TextBox
, TextBlock
, ComboBox
, etc
Upvotes: 0
Reputation: 811
This inserts the GridViewColumn directly into the GridView, but it worked for me.
<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>
In order to see the wrapped text fully, you will need to set the height of the rows to be large enough to see this (or do height conversions dynamically).
<My:ToHeightConverter x:Key="heightConverter" />
<Style TargetType="ListViewItem">
<Setter Property="Height" Value="{Binding ElementName=myListView, Path=ActualHeight, Converter={StaticResource heightConverter}}" />
</Style>
And then in the code behind the 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();
}
}
Upvotes: 1