Show/Hide GridViewColumns through ContextMenu
I have a ListView with some GridViewColumns and I'd like to be able to show or hide them through checkable items in a ContextMenu.
MainView.xaml:
<ListView>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem x:Name="cma" Header="a" IsCheckable="True" IsChecked="True"/>
<MenuItem 开发者_C百科x:Name="cmb" Header="b" IsCheckable="True"/>
<MenuItem x:Name="cmc" Header="c" IsCheckable="True" IsChecked="True"/>
<MenuItem x:Name="cmd" Header="d" IsCheckable="True"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView>
<c:GridViewColumnExt c:GridViewColumnExt.IsVisible="{Binding ElementName=cma, Path=IsChecked}">
<GridViewColumnHeader Content="a"/>
</c:GridViewColumnExt>
<c:GridViewColumnExt c:GridViewColumnExt.IsVisible="{Binding ElementName=cmb, Path=IsChecked}">
<GridViewColumnHeader Content="b"/>
</c:GridViewColumnExt>
<c:GridViewColumnExt c:GridViewColumnExt.IsVisible="{Binding ElementName=cmc, Path=IsChecked}">
<GridViewColumnHeader Content="c"/>
</c:GridViewColumnExt>
<c:GridViewColumnExt c:GridViewColumnExt.IsVisible="{Binding ElementName=cmd, Path=IsChecked}">
<GridViewColumnHeader Content="d"/>
</c:GridViewColumnExt>
</GridView>
</ListView.View>
</ListView>
GridViewColumnExt.cs:
public class GridViewColumnExt : GridViewColumn
{
private double _visibleWidth = double.NaN;
public bool IsVisible
{
get { return (bool)GetValue(IsVisibleProperty); }
set { SetValue(IsVisibleProperty, value); }
}
public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.Register("IsVisible", typeof(bool), typeof(GridViewColumnExt), new FrameworkPropertyMetadata(true, OnIsVisibleChanged));
private static void OnIsVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var newValue = bool.Parse(e.NewValue.ToString());
var column = (GridViewColumnExt)d;
var header = (GridViewColumnHeader)column.Header;
header.IsEnabled = newValue;
if (newValue)
{
column.Width = column._visibleWidth;
header.IsEnabled = true;
header.Visibility = Visibility.Visible;
}
else
{
column._visibleWidth = column.Width;
column.Width = 0;
header.IsEnabled = false;
header.Visibility = Visibility.Collapsed;
}
}
}
MainViewModel.cs (Never mind, the solution doesn't need this)
The problem:
- When the window is first shown, columns a and c are visible
- When the ContextMenu is first shown, columns a and c become hidden and only column b is shown. Also, only column b is checked in the ContextMenu
Does anyone know what causes this?
Solution:
Removed binding to ViewModel properties and and just set the MenuItem.IsChecked to a default value. By the way, if anyone has an even better way of handling this kind of stuff, please let me know :)
FallbackValue is for when a binding is unable to return a value. Column b is checked and visible because you're setting it to true in the constructor. Update your constructor appropriately.
public class MainViewModel
{
public MainViewModel()
{
ColumnChecked_a = true;
ColumnChecked_b = true;
ColumnChecked_c = true;
}
}
Also, I'm thinking the columns' visibility changes because the contextmenu maybe isn't "created" until the right-click. Try a normal menu and see if that works, yeah.
精彩评论