2

I'm puzzled how to simply right-align some columns in a GridView without writing tons of markup for every column.

I can't use a static CellTemplate, because cell templates are ignored when you set DisplayMemberBinding at the same time (see remarks in MSDN). Without DisplayMemberBinding, I would be back at one custom cell template per column because the binding is different, and that's what I want to avoid.

So a style would be great like we can use for the header:

<GridViewColumn DisplayMemberBinding="{Binding Bla}" HeaderContainerStyle="{StaticResource RightAlignStyle}" />

However, I can't find a property to set a style for cell items.

Probably I'm missing the forest through the trees...

H.B.
  • 166,899
  • 29
  • 327
  • 400
realMarkusSchmidt
  • 4,303
  • 1
  • 29
  • 33
  • Hi, columns of what types are you using - just DataGridTextBoxColumns? –  Nov 14 '11 at 11:23
  • Here's a similar one, wonder if it's of help: http://stackoverflow.com/questions/3652318/datagrid-text-alignment –  Nov 14 '11 at 11:51
  • @Dmitry, in this case, it's read-only, so I'm using `TextBlock`. Very simple, that's why I want to avoid custom `CellTemplate`s for many columns. – realMarkusSchmidt Nov 14 '11 at 12:24
  • Regarding the other SO question you mentioned: It looks like this solution wouldn't allow me to set the align _per column_, only for the whole grid. On the other hand, I'm just scratching the surface of what is possible with WPF, so maybe I overlook something obvious. Thank you very much though! – realMarkusSchmidt Nov 14 '11 at 12:30
  • WPF `ListView` does not have concept of `cell`. I recommend using much better UI control i.e. `DataGrid` for this. – WPF-it Nov 14 '11 at 13:24
  • AngelWPF - Neither does DataGrid. –  Nov 14 '11 at 13:42
  • @AngelWPF, I don't know what you mean by "no concept of cell". For each column, there is a header, and items (or cells). There is a `GridViewColumn.HeaderTemplate`, and a `GridViewColumn.CellTemplate`. Regarding `DataGrid`: As I need this only for display, not for editing, I preferred ListView to keep it lean (but I don't know if this assumption makes sense actually). – realMarkusSchmidt Nov 14 '11 at 15:31
  • @Dmitry, I disagree. DataGrid has a clearly defined and identified content entity called `DataGridCell`. `ListView` does not. @markus, The `ListView.CellTemplate` is basically a logical concept of what template will be presented under a column at each row. Sadly it doesnt correspond to `cell` as ListView has no such entity called `ListViewCell` – WPF-it Nov 15 '11 at 05:23

2 Answers2

1

Markus, here's what I would do. Bite the bullet and for the price of writing 10 lines of code get yourself a first class support for alignments and any other unsupported properties. you can traverse the visual tree and look up for PART_* thing for the heavy fine tunung.

The solution is:

1. Alignable Column Class:

namespace AlignableCellsProject
{
    public class AlignableTextColumn: DataGridTextColumn
    {
        protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
            FrameworkElement element = base.GenerateElement(cell, dataItem);
            element.SetValue(FrameworkElement.HorizontalAlignmentProperty, this.HorizontalAlignment);

            return element;
        }

        protected override System.Windows.FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        {
            FrameworkElement element = base.GenerateEditingElement(cell, dataItem);
            element.SetValue(FrameworkElement.HorizontalAlignmentProperty, this.HorizontalAlignment);

            return element;
        }

        public HorizontalAlignment HorizontalAlignment
        {
            get { return (HorizontalAlignment)this.GetValue(FrameworkElement.HorizontalAlignmentProperty); }
            set { this.SetValue(FrameworkElement.HorizontalAlignmentProperty, value); }
        }
    }
}

2. Consumer's XAML:

<Window x:Class="AlignableCellsProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AlignableCellsProject"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="g" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <local:AlignableTextColumn HorizontalAlignment="Left"
                                           Width="200" Binding="{Binding}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

3 - Consumer's Code Behind:

namespace AlignableCellsProject
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.Loaded += 
                (o, e) => 
                {
                    this.g.ItemsSource = Enumerable.Range(1, 3);
                };
        }
    }
}

  • Thank you very much for your work! Interesting approach, I will give this a try. Maybe I can even extend this to "guess" the correct alignment based on the type of the bound property (e. g. numeric -> right-align, text -> left-align). – realMarkusSchmidt Nov 14 '11 at 15:35
  • That is an interesting adjustment by all means! –  Nov 14 '11 at 15:45
-1

I am not using .Net 4.0 but this serves the purpose...

   <tk:DataGrid ItemsSource="{Binding}" IsReadOnly="True" AutoGenerateColumns="True">
        <tk:DataGrid.Resources>
            <Style x:Key="MyAlignedColumn" TargetType="{x:Type tk:DataGridCell}">
                <Setter Property="HorizontalAlignment" Value="Right"/>
                <Setter Property="HorizontalContentAlignment" Value="Left"/>
            </Style>
        </tk:DataGrid.Resources>
        <tk:DataGridTextColumn Header="Name"
                               CellStyle="{StaticResource MyAlignedColumn}"
                               Binding="{Binding Name, Mode=TwoWay}"/>
    </tk:DataGrid>
WPF-it
  • 19,625
  • 8
  • 55
  • 71
  • +1, I have used this. To add to this, if we want a particular column to exhibit alignment then we can set `DataGridColumn.CellStyle={StaticResource CellAlignmentStyle}` where `CellAlignmentStyle` is the key assigned to the style above. –  Nov 15 '11 at 08:10
  • 4
    The question was for `ListView` with a `GridView` not `DataGrid`. – Olly Mar 26 '14 at 12:12