【问题标题】:Can I filter items displayed in RepositoryItemLookUpEdit?我可以过滤 RepositoryItemLookUpEdit 中显示的项目吗?
【发布时间】:2013-07-26 19:13:50
【问题描述】:

这是我的一些代码:

List<Targets> _myList = new List<Targets>();
RepositoryItemLookUpEdit MyRepositoryItemLookUpEdit = new RepositoryItemLookUpEdit();
MyRepositoryItemLookUpEdit.DataSource = _myList;

public class Targets
{
    public string Target { get; set; }
    public bool ShouldDisplay { get; set; }
    public Targets(string target)
    {
        Target = target;
        ShouldDisplay = true;
    }
}

我的问题:是否有可能在显示下拉列表时只显示带有ShouldDisplay == true 的目标?

注意_myList 可以被事件处理程序访问,所以列表中的项目和它们的ShouldDisplay 属性在运行时被修改。例如:

public void MyGrid_CellValueChanging(object sender, CellValueChangedEventArgs e)
{
    if (/* the focused Target item appears more than 3 times in the grid*/)
    { 
        thisTarget.ShouldDisplay = false; // so it will be visually removed from the lookUpEdit and the user cannot select the same one anymore
    }
}

顺便说一句,在 CellValueChanging 事件处理程序中分配给 DataSource 是不合适的,因为一旦重新分配 DataSource,用户所做的任何更改都将被丢弃。

【问题讨论】:

  • 你为什么要分配 this = new List();?
  • 我的回答解决了你的问题吗?

标签: c# winforms gridview user-interface devexpress


【解决方案1】:

改变这一行

MyRepositoryItemLookUpEdit.DataSource = new List<Targets>();//i can't get why you are assigning empty list

//your list which is List<Targets> and contains values. Not the empty one like above
MyRepositoryItemLookUpEdit.DataSource = yourList.Where(x=>x.ShouldDisplay ).ToList();

编辑

编辑问题后,您需要实施

INotifyPropertyChanged

界面。然后,每当更改 ShouldDisplay 的值时,您都需要重新绑定。查看工作示例here

【讨论】:

  • 嘿,谢谢 Ehsan,对不起,我之前的问题令人困惑。我刚刚修改了它。
【解决方案2】:

当您使用 bindingSource 并将 RepopsitoryItemLookUpEdit 绑定到 bindingsource 时,您不必重新分配数据源。

public partial class Form1 : Form
{
    private readonly List<Targets> _targetses;
    private BindingList<Targets> _fiList;

    public Form1()
    {
        InitializeComponent();

        this._targetses = new List<Targets>();
        this._targetses.Add(new Targets("Sample"));
        this._targetses.Add(new Targets("Sample"));
        this._targetses.Add(new Targets("Sample"));
        this._targetses.Add(new Targets("Sample") {ShouldDisplay = false});

        this.bindingSource1.DataSource = this.FilteredList;
        this.lookUpEdit1.Properties.DataSource = this.bindingSource1;
        this.bindingSource1.ListChanged += BindingSource1OnListChanged;

        this._targetses[1].ShouldDisplay = false;
    }

    public BindingList<Targets> FilteredList
    {
        get
        {
            return this._fiList ??
                   (this._fiList = new BindingList<Targets>(this._targetses.Where(x => x.ShouldDisplay).ToList()));
        }
    }

    private void BindingSource1OnListChanged(object sender, ListChangedEventArgs listChangedEventArgs)
    {
        this._fiList.Clear();
        foreach (Targets t in this._targetses.Where(x => x.ShouldDisplay)) { this._fiList.Add(t); }
    }

    #region Nested type: Targets

    public class Targets : INotifyPropertyChanged
    {
        private bool _bShouldDisplay;
        private string _sTarget;

        public Targets(string target)
        {
            Target = target;
            ShouldDisplay = true;
        }

        public string Target
        {
            get { return this._sTarget; }
            set
            {
                if (this._sTarget == value)
                    return;

                this._sTarget = value;
                this.OnPropertyChanged();
            }
        }

        public bool ShouldDisplay
        {
            get { return this._bShouldDisplay; }
            set
            {
                if (this._bShouldDisplay == value)
                    return;

                this._bShouldDisplay = value;
                this.OnPropertyChanged();
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}

结果:

【讨论】:

    【解决方案3】:

    编辑:如果它不会妨碍工作流程(如果数据加载速度足够快,可以实时编辑和重新加载),我建议将用户端数据和数据库数据分开。您可以在表中添加一个位字段来存储是否应显示某个项目,当您从数据库中获取数据时过滤数据以最初显示它,然后在进行更改时将 ShouldDisplay 设置为 false,写入到数据库中,将其从列表中删除,然后刷新列表。

    当然,由于列表中的数据很多,这种解决方案可能不可行。

    原答案:

    Ehsan 的建议就是我要发布的内容。另一种选择是遍历主要目标列表中的项目(无论您将下拉列表数据绑定到什么)并创建一个新列表,如下所示:

    List<string> newList = new List<string>();
    foreach (Targets t in targetsList)
    {
        if (t.ShouldDisplay == true) { newList.Add(t.Target); }
    }
    

    然后将下拉列表数据绑定到 newList 而不是您的 targetsList。但我不确定 RepositoryItemLookUpEdit 的确切功能,所以这个解决方案可能不起作用。当您只想显示信息时这很好,但如果您必须与数据本身交互可能会更尴尬。一切都取决于你用它做什么。

    【讨论】:

    • 谢谢马修。但这不是我想要的。我刚刚修改了问题描述。
    • 将值放入 _mylist 的代码在哪里?用户是否在运行时添加它们?
    • 是的,很像。有代码从数据库中读取一个表并在初始化时填充_myList
    • 啊,好的。该表是否有“ShouldDisplay”字段,或者该属性是否基于其他内容?如果它是表中的一个字段,您可以在填充列表时过滤数据,然后在进行更改时使用 Ehsan 所说的重新填充和刷新列表。
    • 不,它不是基于表格字段...我现在正在查看他的示例。谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多