![](/img/trans.png)
[英]C# WPF, ListView and GridView, dynamic columns, and issues with data binding
[英]C# WPF ListView with GridView - add/remove columns context menu
我正在尝试将上下文菜单添加到ListView(使用GridView)以切换列的可见性。 这是一个简单的菜单-仅包含所有可用列的列表,如果选中了列名,则该列应可见。
我的ListView与GridView一起显示。 每列的GridViewColumnHeader具有与具有相同Name和Header值的ContextMenu MenuItem匹配的Name属性和Header属性。 我的问题是,我无法弄清楚如何在不迭代所有列的情况下通过GridViewColumnHeader的名称来选择GridViewColumn。
我可以按索引选择一个列,但是由于如果用户对列进行重新排序,则列索引会更改,因此无法使用。
有没有一种方法可以通过标题数据选择列? 我在想这样的事情:
MenuItem m = e.Source as MenuItem;
GridView gv = (GridView)list.View;
GridViewColumn gvc = gv.Columns[m.Name];
//code to make width 0 or Auto goes here...
似乎没有内置方法可用于此目的。 您可以使用LINQ表达式:
var col = gv.Columns.FirstOrDefault(it => it.Header == "name");
但是它将迭代内部的列。 我相信迭代会很快。 避免完全迭代的另一种方法是订阅CollectionChanged
事件并保存列标题和列之间的映射。 但这是棘手的方式。
private Dictionary<object, GridViewColumn> _columns = new Dictionary<object, GridViewColumn>();
public MainWindow()
{
InitializeComponent();
gv.Columns.CollectionChanged += Columns_CollectionChanged;
}
private void Columns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if((e.Action==NotifyCollectionChangedAction.Remove
|| e.Action==NotifyCollectionChangedAction.Replace)
&& e.OldItems!=null)
{
foreach(GridViewColumn oldItem in e.OldItems)
{
if(_columns.ContainsKey(oldItem.Header)) _columns.Remove((oldItem.Header));
}
}
if(e.NewItems!=null)
{
foreach(GridViewColumn newItem in e.NewItems)
{
_columns[newItem.Header] = newItem;
}
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
gv.Columns.CollectionChanged -= Columns_CollectionChanged;
}
catch { }
}
private GridViewColumn GetColumn(string header)
{
GridViewColumn column = null;
_columns.TryGetValue(header, out column);
return column;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.