簡體   English   中英

具有GridView的C#WPF ListView-添加/刪除列上下文菜單

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM