0

I have a class with some string properties and each class is displayed as a row in a data grid. Each property has a column of its own. If two adjacent properties are empty, I would like to merge those two columns for that particular row. I am open to using a datagrid or a listview as long as it does the job. E.g.

public class MyClass
{
    string name { get; set;}
    string age { get; set;}
    string sex { get; set;}
    double income { get; set;}
}

Merged Column

schwarz
  • 501
  • 7
  • 28

1 Answers1

1

You better use an ItemsControl for these kinds of situations. My suggestion is to use a Grid as ItemsPanel and instead of say 100 instances of MyClass, implement a Cell class and use 400 of them (each for one cell) and set their exact row and column in code.

You will need a GridHelper which you can find it in this link

public class Cell
{
    public int RowIndex { get; set; }
    public int ColumnIndex { get; set; }
    public int ColumnSpan { get; set; }
    public string Data { get; set; }
    public CellType CellType { get; set; } //you can also add an enum for CellType
}

<ItemsControl ItemsSource="{Binding AllCells}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid 
                v:GridHelper.ColumnsCount="{Binding TotalColumns}"
                v:GridHelper.RowsCount="{Binding TotalRows}">
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Row" Value="{Binding Path=RowIndex}"/>
            <Setter Property="Grid.Column" Value="{Binding Path=ColumnIndex}"/>
            <Setter Property="Grid.ColumnSpan" Value="{Binding Path=ColumnSpan}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

If you need different types of cells, you can add this to the ItemContainerStyle:

<Style.Triggers>
    <DataTrigger Binding="{Binding Path=CellType}" Value="NumericCellType">
        <Setter Property="ContentTemplate" Value="{StaticResource templateNumericCell}"/>
    </DataTrigger>
    <DataTrigger Binding="{Binding Path=CellType}" Value="GeneralCellType">
        <Setter Property="ContentTemplate" Value="{StaticResource templateGeneralCell}"/>
    </DataTrigger>
</Style.Triggers>

Or else you can implement a single template:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Data}"/>
    </DataTemplate>
</ItemsControl.ItemTemplate>
Community
  • 1
  • 1
Bizhan
  • 16,157
  • 9
  • 63
  • 101
  • 1
    I forgot to add ColumnSpan which I did now – Bizhan Nov 20 '14 at 10:40
  • Hey Bizz, thanks for your answer. Btw, how do u get the DataGrid like look? – schwarz Nov 20 '14 at 12:21
  • 1
    It all depends on your preference, e.g. you can use DataGridColumnHeader for the first row cells, and use a TextBox with a Border for the other cells. a border with full span (ColumnSpan=4) as the background of a full row which is invisible and has a trigger on mouseOver to turn it to visible and so on. – Bizhan Nov 20 '14 at 12:44