Reputation: 9891
How can I prevent a user from resizing GridViewColumns withing a ListView control?
Upvotes: 27
Views: 36903
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.
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
Reputation: 940
I was able to do something similar with the instructions in this post
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
Reputation: 466
A smooth solution:
<GridViewColumn ...>
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
Upvotes: 0
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
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
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