【问题标题】:Change value of all controls of a specific type without causing indefinite loop更改特定类型的所有控件的值而不会导致无限循环
【发布时间】:2013-05-03 15:08:22
【问题描述】:

我有一种情况,我的表单上的几个选项卡上有几个(假设现在是 10 个)DevExpress LookUpEdit 控件(有点像 Windows 的 DropDown 控件)。所有这 10 个控件都是相同的,因为它们使用相同的数据源来获取信息。我想要做的是,如果 10 个控件中的任何一个值发生变化,那么我希望它在其他 9 个控件中也发生变化。因为我的表单上有其他我不想更改的此类控件,所以我只是向Tag 属性添加了一个字符串值,并使用方法搜索此类型的所有控件,并将 Tag 属性设置为特定的字符串。

我最初认为我可以创建一个通用方法来更改所有其他控件的文本并将其分配给每个控件的 TextChanged 事件,但我很快发现一旦我分配它们就会相互抵消将一个控件的值更改为另一个(因为本质上,一旦我更改了一个控件的值,它就会调用相同的方法并尝试更改其余部分)。

对不起,如果它令人困惑,但这里有一些关于我想要做什么的代码......现在,假设我只有 2 个控件......lookupWeightlookupBicycleWeight。在每个TextChanged 事件中,我有这个:

    private void OnLookupWeight_TextChanged(object sender, EventArgs e)
    {
        OnLookupWeight_TextChanged<LookUpEdit>(sender, e);
    }

这叫这个:

    private void OnLookupWeight_TextChanged<T>(object sender, EventArgs e)
    {
        var controls = GetAll(tabPageSpecifications, typeof(T));

        foreach (var control in controls)
        {
            if (control.Tag != null)
                if (control.Tag.ToString() == "Weight")
                    if(control.Name != (sender as LookUpEdit).Name)
                        (control as LookUpEdit).EditValue = (sender as LookUpEdit).Text;
        }

    }

GetAll 是一个简单的方法,它返回给定 Control 的所有控件,包括子控件:

    /// <summary>
    /// method to get all child & sub-child controls within a control by type
    /// </summary>
    /// <param name="control">the control we're searching in (use this for the form)</param>
    /// <param name="type">The control type we're looking for (i.e; TextBox)</param>
    /// <returns></returns>
    public IEnumerable<Control> GetAll(Control control, Type type = null)
    {
        var controls = control.Controls.Cast<Control>();
        //check the all value, if true then get all the controls
        //otherwise get the controls of the specified type
        if (type == null)
            return controls.SelectMany(ctrl => GetAll(ctrl, type)).Concat(controls);
        else
            return controls.SelectMany(ctrl => GetAll(ctrl, type)).Concat(controls).Where(c => c.GetType() == type);
    }

我知道我的 OnLookupWeight_TextChanged 方法并不完全是通用的,因为我转换为 LookupEdit 类型,但我只是想让它在这一点上正常工作,然后再返回并进行更改。

如您所见,if(control.Name != (sender as LookUpEdit).Name) 行是OnLookupWeight_TextChanged 再次被触发并基本上自行取消的位置。

任何关于如何实现这一点的帮助或指导都会很棒。

【问题讨论】:

  • 我认为您需要使用数据绑定:在 UI 上的控件之间存在复杂关系的情况下最直接的解决方案。检查是否可以使用这些控件。

标签: c# winforms devexpress


【解决方案1】:

只需更改尚未具有相同 Text 值的那些:

    foreach (var control in controls)
    {
        if (control.Tag != null)
            if (control.Tag.ToString() == "Weight")
                if((control as LookUpEdit).EditValue != (sender as LookUpEdit).Text)
                    (control as LookUpEdit).EditValue = (sender as LookUpEdit).Text;
    }

【讨论】:

    【解决方案2】:

    听起来,当控件的文本从该例程中更改时,不应运行 OnLookupWeight_TextChanged 中的代码。您可以使用实例变量来禁用运行它,除非更改来自外部。例如:

        private Boolean InProgress;
        private void OnLookupWeight_TextChanged<T>(object sender, EventArgs e)
        {
            if (!InProgress)
            {
                InProgress=true;
                var controls = GetAll(tabPageSpecifications, typeof(T));
    
                foreach (var control in controls)
                {
                     if (control.Tag != null)
                         if (control.Tag.ToString() == "Weight")
                             if(control.Name != (sender as LookUpEdit).Name)
                                 (control as LookUpEdit).EditValue = (sender as LookUpEdit).Text;
                }
                InProgress = false;
            }
        }
    

    【讨论】:

      【解决方案3】:

      为什么不对所有 10 个控件使用相同的绑定源?

      当您更改其中一个中的选定值时,所有值都会改变。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-22
        • 2019-03-29
        • 2015-01-16
        • 2021-12-07
        • 1970-01-01
        • 2016-05-01
        • 2023-04-09
        相关资源
        最近更新 更多