WPF Listview that uses GridView Column content alignment

Answered WPF Listview that uses GridView Column content alignment

  • Friday, December 21, 2007 4:53 AM
     
     

    Is there a way to right align one column's content and left align another in a listview? Also is there a way to do it programatically rather than in XAML?

     

    I downloaded sample code from http://msdn2.microsoft.com/en-us/library/ms771480.aspx but unfortunately that does not have it.

     

    Can someone help please?

     

    Regards,

    LearningWPFnDotNet

All Replies

  • Friday, December 21, 2007 10:17 AM
     
     
    You can achieve this in two ways:
    • Bind the property HorizontalContentAlignment in your DataTemplate to the value of your business object that is responsible for the alignment. You will definitely have to use converter in the binding.
    • Create 2 different templates, one aligned left and one aligned right. Create DataTemplateSelector class that will return appropriate DataTemplate. Assign the template selector to the ListView. Check this sample here.
  • Friday, December 21, 2007 1:04 PM
     
     

    Thanks Stefan,

    Sorry I am yet to come to that stage that I could completely understand what you are saying but I wish it could be done with one liner or may be two. I have to admit I am a little too lazy 

     

    Is there not a simple alignment property for the gridview column (wishful e.g. gvc2.HorizontalAlignment = "Right"), I think it only makes sense, right!? It could NOT have been possibly overlooked by the MS ListView developers!!!

     

    GridViewColumn gvc2 = new GridViewColumn();

    gvc2.HorizontalAlignment = "Right"; //Wish for something like this that does not seem to exist

    ...

    myGridView.Columns.Add(gvc2);

     

    Any other simpler idea welcome! Otherwise I may end up left padding with spaces to make it look "     right aligned", what else can I do?

     

    Thanks,

    LearningWPFnDotNet

  • Friday, December 21, 2007 11:51 PM
     
     Answered

    Below is an example you can view in XamlPad that demonstrates how to use a CellTemplate to control the alignment of a column.  (If you need a sample of how to create and set a cell template in code, see this post.)

     

    Code Block

     

    <Page

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

      <Page.Resources>

        <XmlDataProvider x:Key="CharacterData">

          <x:XData>

            <Data xmlns="">

              <Character First="Bart" Last="Simpson" />

              <Character First="Homer" Last="Simpson" />

              <Character First="Lisa" Last="Simpson" />

              <Character First="Maggie" Last="Simpson" />

              <Character First="Marge" Last="Simpson" />

            </Data>

          </x:XData>

        </XmlDataProvider>

      </Page.Resources>

      <ListView ItemsSource="{Binding Source={StaticResource CharacterData},

          XPath=Data/Character}">

        <ListView.View>

          <GridView>

            <GridViewColumn Width="100" Header="First Name">

              <GridViewColumn.CellTemplate>

                <DataTemplate>

                  <TextBlock Width="98" Margin="-6,0"

                      TextAlignment="Right" Text="{Binding XPath=@First}" />

                </DataTemplate>

              </GridViewColumn.CellTemplate>

            </GridViewColumn>

            <GridViewColumn Width="100" Header="Last Name">

              <GridViewColumn.CellTemplate>

                <DataTemplate>

                  <TextBlock Width="100" Margin="-6,0"

                      TextAlignment="Left" Text="{Binding XPath=@Last}" />

                </DataTemplate>

              </GridViewColumn.CellTemplate>

            </GridViewColumn>

          </GridView>

        </ListView.View>

      </ListView>

    </Page>

     

     

     

    LearningWPFnDotNet wrote:

    Is there not a simple alignment property for the gridview column (wishful e.g. gvc2.HorizontalAlignment = "Right"), I think it only makes sense, right!? It could NOT have been possibly overlooked by the MS ListView developers!!!

     

    A *lot* was overlooked in this particular control.  It has a lot of hardcoded idiosyncracies and it really lacks extensibility.  Ideally, the content presenters for each cell should have their HorizontalAlignment and VerticalAlignment properties set to Stretch (instead of Left and Top, respectively) and should have a zero margin (instead of a margin of 6 pixels on the left and right and 0 on the top and bottom).  This would allow people to easily align the contents within a cell however they saw fit as well as set their own margins.  Instead, these properties are hardcoded and cannot easily be accessed except via code.

     

    Using the above example, if you want the column to stay right-aligned as it resizes, you will have to bind the TextBlock's width to the corresponding column's width.  This will have to be done in code by walking up the ancestor tree to find the GridViewRowPresenter and then accessing it's Columns property to find the correct column.

     

  • Saturday, December 22, 2007 9:43 PM
     
     

    Thanks Dr.,

    thank you very much for your time and effort, I am yet to try it out but I will, as soon as I get a chance. I am new to this forum (this was my second question) and it's amazing how people just come forward to help you.

     

    Hope MS takes note of your comment about Listview control:

    >>>A *lot* was overlooked in this particular control.  It has a lot of hardcoded idiosyncracies and it really lacks extensibility.  Ideally, the content presenters for each cell should have their HorizontalAlignment and VerticalAlignment properties set to Stretch (instead of Left and Top, respectively) and should have a zero margin (instead of a margin of 6 pixels on the left and right and 0 on the top and bottom).  This would allow people to easily align the contents within a cell however they saw fit as well as set their own margins.  Instead, these properties are hardcoded and cannot easily be accessed except via code.<<<

     

    Thanks everyone for your help,

    LearningWPFnDotNet

  • Thursday, March 27, 2008 4:12 PM
     
     Proposed Answer

    Ian Griffiths provides a simple way to get ListView columns to align and resize properly.  See his blog entry at http://www.interact-sw.co.uk/iangblog/2007/05/30/fill-wpf-listview-columns.  Basically, you just need the following XAML to make each ListViewItem stretch align instead of left align:

     

    Code Snippet

        <ListView.ItemContainerStyle>
          <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
          </Style>
        </ListView.ItemContainerStyle>

     

    Then you can use CellTemplates with TextBlocks with any text alignment you want, and the TextBlocks will automatically resize when the columns are resized.

    • Proposed As Answer by Joel Stein Thursday, January 21, 2010 3:46 PM
    •  
  • Thursday, March 27, 2008 9:58 PM
     
     

     Bill Menees wrote:

    Ian Griffiths provides a simple way to get ListView columns to align and resize properly.

     

    The HorizontalContentAlignment approach is fine if you just want to stretch all content presenters in the row or if you want to individually set alignment on template elements.

     

    The approach I've shown above actually compensates for the default margin that is hard coded (again... bad control!) into the GridViewRowPresenter's content presenters.  Ian describes this problem in the post that you referenced, but leaves the resolution for a future post.  Don't know if he ever followed up, but the above example is one common way to deal with it.  For a less common but more powerful approach, you can read my description of the problem in this earlier thread.

  • Sunday, April 27, 2008 4:28 PM
     
     

    Brilliant! Pretty much every adventure I've had with ListView and GridView so far has been an adventure in frustration. I've been rewriting from scratch most of the time, because I can't get the ListView and GridView to do what I want.

     

    This one addition might just solve the majority of problems I'm having. (It solved the immediate problem and hand, and I'm pretty sure it would have solved the other ListView rewrite in my current project as well. I can't believe nothing has been done about these controls in 3.0 or 3.5. :-/

     

    Thanks.

     

    >>

    Code Snippet

        <ListView.ItemContainerStyle>
          <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
          </Style>
        </ListView.ItemContainerStyle>

     

  • Tuesday, May 19, 2009 12:33 PM
     
      Has Code
    Hello All, How to aligh column programatically like: gvc2.HorizontalAlignment = "Right"; // gvc2 is column from above discussion Examples shown here are of adding it using XAML, but I need it to align programatically. Thanks In Advance, Salahuddin
  • Tuesday, July 28, 2009 5:54 PM
     
      Has Code
    Hi,

    I tried your example...but it is not working for me. The column is still not stretched..:-( Do you have an idea why not?

    Here is my code:

    <Window x:Class="Window11"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:s="clr-namespace:System;assembly=mscorlib"
        Title="Window11" Height="300" Width="300">
        <Grid>
            <Grid.Resources>
                <x:Array Type="{x:Type s:String}" x:Key="items">
                    <s:String>Foo</s:String>
                    <s:String>Bar</s:String>
                    <s:String>Spong</s:String>
                </x:Array>
            </Grid.Resources>
    
            <ListView ItemsSource="{StaticResource items}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
    
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="HorizontalContentAlignment"
                    Value="Stretch" />
                    </Style>
                </ListView.ItemContainerStyle>
    
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Data" >
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBox Text="{Binding .}"  />
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Length"
                 DisplayMemberBinding="{Binding Length}" />
                    </GridView>
                </ListView.View>
            </ListView>
    
        </Grid>
    
    </Window>
    
    and as a result the columns are still pressed to the left side. I would like to add a screenshot, but is not possible here...I dot know why it is not working for me.

    Greeting,
    Kame

  • Thursday, January 21, 2010 3:49 PM
     
     
    make sure to set the TextAligment property in the data template to "Center" or "Right" or whatever.

    i.e.
    (in my case)

    <TextBlock Text="{Binding Path=Name}" TextAlignment="Center"/>