Joachim Kerschbaumer
Joachim Kerschbaumer

Reputation: 9891

Prevent user from resizing columns with WPF ListView

How can I prevent a user from resizing GridViewColumns withing a ListView control?

Upvotes: 27

Views: 36903

Answers (6)

Loerinc
Loerinc

Reputation: 21

I wanted to create 20 pixel wide GridView columns that only have one character. These did not require resizing, but the other columns did. The problem with the resizing was that due to the 18 pixel wide Thumbs, it was hardly possible to click on the headers of the columns, and the ToolTips were also difficult to display. I thought it would be nice to get rid of the annoying Thumbs.

enter image description here enter image description here

I found Thumb here: 1038 private Thumb _headerGripper;

I didn't want to get the GridViewHeaderRowPresenter by moving up from a columns[n].header, so I also looked for it: 549 private GridViewHeaderRowPresenter _gvheaderRP;

The ListView was on the second tab of a TabControl, so I put the Thumb unthumbing in the PreviewMouseMove event handler.

...
<ListView x:Name="TestListView" PreviewMouseMove="TestListView_PreviewMouseMove">
...
    <ListView.View>
        <GridView x:Name="TestGridView">
...

...
using System.Reflection;
using System.Windows.Media;
using System.Windows.Controls.Primitives;
...
private readonly int FIXCOLWIDTH = 20;
private bool _SetCols = true;
private void TestListView_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (_SetCols)
    {
        _SetCols = false;

        GridViewHeaderRowPresenter wPres = TestGridView.GetFieldValue<GridViewHeaderRowPresenter>("_gvheaderRP");
        for (int n = 0; n < VisualTreeHelper.GetChildrenCount(wPres); n++)
        {
            if (VisualTreeHelper.GetChild(wPres, n) is GridViewColumnHeader wHeader && wHeader.Column?.Width == FIXCOLWIDTH)
            {
                if (wHeader.GetFieldValue<Thumb>("_headerGripper") is Thumb wThumb)
                {
                    wThumb.Width = 0;
                }
            }
        }
    }
}
...

public static class ReflectionExtensions
{
    public static T GetFieldValue<T>(this object aObj, string aName)
    {
        BindingFlags wBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
        FieldInfo wField = aObj.GetType().GetField(aName, wBindingFlags);
        return (T)wField?.GetValue(aObj);
    }
}

Upvotes: 0

jmlumpkin
jmlumpkin

Reputation: 940

I was able to do something similar with the instructions in this post

Link

I wasn't able to use a full XAML solution, since I was building everything in my code behind due to the dynamics of it. Worked great on the first try.

Upvotes: -2

mca
mca

Reputation: 466

A smooth solution:

<GridViewColumn ...>
    <GridViewColumn.HeaderContainerStyle>
        <Style TargetType="{x:Type FrameworkElement}">
            <Setter Property="IsHitTestVisible" Value="False"/>
        </Style>
    </GridViewColumn.HeaderContainerStyle>
</GridViewColumn>

Upvotes: 0

InTheZone
InTheZone

Reputation: 459

Darkonekt's answer is good, however it may be preferable to set IsHitTestVisible to false instead of IsEnabled. This has the benefit of not greying out the headers.

<GridView.ColumnHeaderContainerStyle>
    <Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="{x:Type GridViewColumnHeader}">
        <Setter Property="IsHitTestVisible" Value="False"/>
    </Style>
</GridView.ColumnHeaderContainerStyle>

Upvotes: 32

Jonathan Alfaro
Jonathan Alfaro

Reputation: 4376

For those looking for a quicker and simpler answer.

Set IsEnabled to False in the ColumnHeaderContainerStyle. This will prevent the user from resizing.

Like this:

<GridView.ColumnHeaderContainerStyle>
  <Style TargetType="{x:Type GridViewColumnHeader}">
       <Setter Property="IsEnabled" Value="False"/>
  </Style>
</GridView.ColumnHeaderContainerStyle>

If you want to fix the disabled grayed out color add a trigger on the IsEnabled property and fix what you need.

<GridView.ColumnHeaderContainerStyle>
   <Style TargetType="{x:Type GridViewColumnHeader}">
       <Setter Property="IsEnabled" Value="False"/>
    <Style.Triggers>
       <Trigger Property="IsEnabled" Value="False">                
          <Setter Property="TextElement.Foreground" Value="Black"/>                       
       </Trigger>
    </Style.Triggers>
  </Style>
</GridView.ColumnHeaderContainerStyle>

This answer might not be as elegant as other posted; but in my case all I needed was a quick way of doing it.

Hope this helps someone.

Upvotes: 36

Joachim Kerschbaumer
Joachim Kerschbaumer

Reputation: 9891

i found a solution and probably it will help someone else someday ;)

you have to override the GridViewColumnHeader's ControlTemplate (default template is here ) and remove the PART_HeaderGripper from the template in order to prevent resizing of your columns.

there is another solution that comes up with subclassing GridViewColumn described here. for representation purposes i prefer xaml only solutions though

Upvotes: 15

Related Questions