0
votes

Using C# and WPF, I am trying to wrap the text in a DataGrid Column. I am setting the ItemsSource of the DataGrid in the code-behind, rather than using data binding.

As far as I can tell, there isn't a 'wrap' property for a datagrid, but it is possible to nest cell data inside of a textblock that can be wrapped. Unfortunately everything I've seen to do this uses data binding in the xaml, which would require a lot of refactoring, so I am trying to avoid it.

My xaml item:

<DataGrid x:Name="dgvOrderItems" AutoGeneratedColumns="DgvOrderItems_AutoGeneratedColumns" Height="570" VerticalAlignment="Stretch" Width="auto" HorizontalAlignment="Stretch" FontSize="10" Padding="0" Margin="0,20,0,0" ></DataGrid>

My code behind for the DgvOrderItems_AutoGeneratedColumns:

dgvOrderItems.SelectionUnit = DataGridSelectionUnit.FullRow;
dgvOrderItems.IsReadOnly = true;
dgvOrderItems.ColumnHeaderHeight = 15;
dgvOrderItems.Columns[0].Header = "Order Item";
dgvOrderItems.Columns[0].Width = 113;
dgvOrderItems.Columns[1].Visibility = Visibility.Hidden;
dgvOrderItems.Columns[2].Header = "Qty.";
dgvOrderItems.Columns[2].Width = 25;

As yet, I have been unable to find a good way to wrap the "Order Item" if the length exceeds the specified width.

1
You could create a DataTemplate programmatically. You're creating immensely more work for yourself by doing everything wrong vs refactoring, but it's your life. - 15ee8f99-57ff-4f92-890c-b56153
@TerryTyson, I've already looked at the question you referenced, and it is very similar, however, the solution in that case was done in the xaml with data binding. - nherrmann
@EdPlunkett, to be completely honest, I've done some very basic data binding, but I'm not really comfortable with it. Between that, and the fact that I'm going to have to refactor a good bit of code (both my own, and another developer's), I'm hesitant to go that route, but I may just need to bite the bullet and get more comfortable with data binding. When you say that I can create the DataTemplate programatically, do you have an example of that? - nherrmann
Google site:StackOverflow.com create datatemplate programmatically. It's a finicky tedious hassle. You could create it properly in XAML as a resource, and use FindResource to load it. If you're not going to refactor, that's your best bet by miles. At least start getting your feet wet here and there with XAML before committing to a full rewrite. How big is this project? - 15ee8f99-57ff-4f92-890c-b56153

1 Answers

0
votes

After going back and forth with it, I decided to go with what @TerryTyson and @EdPlunkett suggested by refactoring it with better data binding. Thanks guys for the advice.

XAML:

<DataGrid x:Name="dgvOrderItems" Height="570" VerticalAlignment="Stretch" Width="138" HorizontalAlignment="Stretch" FontSize="10" Padding="0" HorizontalScrollBarVisibility="Hidden">
<DataGrid.ColumnHeaderHeight>20</DataGrid.ColumnHeaderHeight>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Order Item" Width="108" Binding="{Binding ItemNumber}">
            <DataGridTextColumn.ElementStyle>
                <Style>
                    <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
        <DataGridTextColumn Header="Qty." Width="30" Binding="{Binding ItemQty}">
            <DataGridTextColumn.ElementStyle>
                <Style>
                    <Setter Property="TextBlock.TextAlignment" Value="Center" />
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Class for my data:

public class SimpleOrderInfo
{
    public string ItemNumber { get; set; }
    public int ItemQty { get; set; }

    public SimpleOrderInfo(string itemNumber, int itemQty)
    {
        this.ItemNumber = itemNumber;
        this.ItemQty = itemQty;
    }
}

Setting my ItemsSource:

public List<SimpleOrderInfo> simpleOrderInfo = new List<SimpleOrderInfo>();
simpleOrderInfo = business.GetSimpleOrderInfo(orderNumber);
dgvOrderItems.ItemsSource = simpleOrderInfo;

I feel like this could still probably be cleaned up some, but it is working, and is much cleaner than what I started with.