如果我只想让一个班级访问我的表格控件怎么办?

时间:2011-08-18 01:01:07

标签: c# winforms

我在我的应用程序中实现了一个Undo / Redo系统,但因为它是一个与我的主窗体不同的类,所以它无法访问它的任何控件。目前我正在将需要撤消或重做的每个控件传递给类的构造函数,但它很快就会成为我项目中最大的构造函数之一。

如果只允许这个类访问我的表单控件,那就太好了。如果我将表单传递给构造函数,我仍然无法访问控件,因为它们都是私有的。我想简单的解决方案是制作我需要公开使用的所有控件,但理想或优雅的解决方案是什么?

P.S。我已经阅读过关于为所有必需的东西设置公共属性并将表单传递给构造函数的技术,但这将最终成为相当多的属性,并且解决方案在这种情况下似乎不太适用。

谢谢!

2 个答案:

答案 0 :(得分:2)

将UI控件或表单传递给类非常非常非常罕见。这只是一个维护/依赖的噩梦。

您不希望您的班级知道您的表单控件,它应该关心的是它的数据。

您的表单了解自己,知道需要保存的数据以及如何将其恢复到正确的控件。

如果您正在寻找的是撤消/重做功能,您需要查看Memento设计模式。除非您有其他业务需要,否则您不需要创建完全属性的类。

对于纪念品模式。

一个简单的对象包含您要保留的状态....

 internal class Memento: IMemento
    {
        private object _state;

        public void SetState(object state)
        {
            _state = state;
        }

        public object GetState()
        {
            return _state;
        }
    }

看护人对象管理表格的纪念品。

 public class Caretaker
    {
        private Dictionary<int,IMemento> _mementos = new Dictionary<int,IMemento>();
        public void AddMemento(int tag, IMemento memento)
        {
            _mementos.Add(tag, memento);
        }

        public IMemento GetMemento(int tag)
        {

            if (_mementos.ContainsKey(tag))
            {
                return _mementos[tag];
            }

            return null;
        }
    }

在改变状态后,表格会向看守人保存新的纪念品。我们利用对象类的极端灵活性......

private void SaveMemento()
{
            Memento memento = new Memento();
            string[] state = {TextBox1.Text, TextBox2.Text};//expand as needed
            memento.SetState(state);
            _caretaker.AddMemento(_currentStateIndex, memento);
            _currentStateIndex++;
}

表单会根据需要恢复。

private void RevertToPreviousState()
        {
            Memento memento = (Memento)_caretaker.GetMemento(--_currentStateIndex);
            string[] state = (string[]) memento.GetState();
            TextBox1.Text = state[0];
            TextBox2.Text = state[1];//expand as needed

        }

忘记IMemento - 只是一个标记界面,如果你想把看管人放在另一个集合中以进行完整的Memento模式实现。

public interface IMemento
    {
    }

答案 1 :(得分:0)

访问跟踪状态的控件不是最好的方法,但如果那是你想要的那么我会建议你访问通过反射私有的控件 http://social.msdn.microsoft.com/forums/en-US/clr/thread/ef7cc349-cf35-4b01-95b3-b71675f9b9d5/