【问题标题】:Manipulating collection from the inside从内部操纵收藏
【发布时间】:2014-04-14 19:15:52
【问题描述】:

我有一组面板,当用户点击它们时会突出显示。我想强制他们表现得像一组单选按钮,所以只有被点击的那个会被突出显示,而其他的则不会。

我想一定有一种方法可以从内部操纵整个集合(将属性设置为 false),因为该事件是由集合中的一个项目触发的。有没有办法让一个项目操纵整个集合?这是应用程序中的一个常见功能,所以我想必须有一个模式来正确地做到这一点。谢谢。

【问题讨论】:

  • 如果您正在谈论从 other 复选框的事件中切换复选框,正确的方法是让包含控件订阅每个复选框上的事件并操作其他复选框从那里开始。
  • 今天早些时候,我有answeredRadioButton 类似的问题,您可以将其转换为您的要求。看看有没有帮助。

标签: c# .net winforms


【解决方案1】:

您可以存储面板集合并处理所需的功能,如下面的代码 sn-p:

List<Panel> Panels;
private void Initialization()
{
    Panels = new List<Panel>();
    Panels.Add(pnl1);
    Panels.Add(pnl2);
    //add all your panels into collection

    foreach(Panel Item in this.Panels)
    {
        //add handle to panel on click event
        Item.Click += OnPanelClick;
    }
}

private void OnPanelClick(object sender, EventArgs e)
{
    foreach(Panel Item in this.Panels)
    {
        //remove highlight from your panels, real property should have other name than Panel.HighlightEnabled
        Item.HighlightEnabled = false;
    }
    ((Panel)sender).HighlightEnabled = true; //add highlight to Panel which invoked Click event
    Application.DoEvents(); //ensure that graphics redraw is completed immediately
}


private void AddNewPanelIntoLocalCollection(Panel panel)
{
    //here you can add new items to collection during program lifecycle
    panel.Click += OnPanelClick;
    this.Panels.Add(panel);
}

【讨论】:

    【解决方案2】:

    我就是这样做的

    public class SelectOne : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        private bool isSelected = false;
        private HashSet<SelectOne> selecteOnes = null;
        public bool IsSelected
        {
            get { return isSelected; }
            set
            {
                if (isSelected == value) return;
                if (isSelected && selecteOnes != null)
                {
                    foreach (SelectOne so in selecteOnes)
                    {
                        if (so == this) continue;
                        so.IsSelected = false;
                    }
                }
                NotifyPropertyChanged("IsSelected");
            }
        }
        public SelectOne() { }
        public SelectOne(bool IsSelected) { isSelected = IsSelected; }
        public SelectedOne(bool IsSelected, HashSet<SelectOne> SelecteOnes)
        {   
            isSelected = IsSelected;
            selecteOnes = SelecteOnes; 
        } 
    }
    

    【讨论】:

      【解决方案3】:

      最终,我确实找到了一种方法,只需一个代表就可以正确地做到这一点。

      在 A 类中,我有一个对象集合 B

      List<B> b = new List<B>
      

      B 类,需要有一个唯一的 ID 和带有 Id 参数的 void 方法的委托

      delegate void DeleteItemDelegate(int id);     
      
      class B
      {
           public int ID {get; set;}
           public DeleteItemDeleate deleteThis {set; get;}
      }
      

      A 类有这样的方法:

          public void RemoveItem(int id)
          {
              for (int x = 0; x < b.Count; x++)
              {
                  if (b[x].id == id)
                  {
                      b.RemoveAt(x);
                  }
              }
          }
      

      将新的 B 对象添加到 List 时,只需将方法 RemoveItem 添加到 B.deleteThis 委托

      B bObject = new B();
      bObject.deleteThis = RemoveItem;
      b.Add(bObject);
      

      现在你需要做的就是在 B 类中添加 DeleteMe 方法

      void DeleteMe()
      {
           // and call local delegate - pointing to metod which actually can manipulate the collection
           deleteThis(id);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多