帮助设计经理课程

时间:2011-09-27 07:30:25

标签: c#

我正在设计一个UI管理器类,它将管理我的所有UI元素(这是一个XNA游戏,因此没有现有的UI框架)但我想知道如何处理我想要UI管理器的情况有权访问其他类无法访问的UI元素中的数据。

例如,我想要一个SetFocus方法来聚焦特定元素,这个方法需要确保先前聚焦的元素失去焦点。单个UI元素本身无法处理这个问题,因为他们无法访问UI元素列表,这意味着管理员必须处理它,但是如何允许管理器和管理器在UI元素上设置变量?

我想到只将当前关注的元素存储在管理器上,但是我并不特别喜欢这个解决方案,并且在给定单个UI元素的情况下,我想查询它以确定它是否具有焦点。即使将当前关注的元素存储在管理器上是有意义的,因为它只是一个变量,我需要处理的其他事情需要数组将数据与元素相关联,如果它存储在管理器上,那么似乎打败了OOP的目的。

我知道我不需要需要以便管理员是唯一可以访问此数据的人,我可以公开所有数据,但那不是好设计。

2 个答案:

答案 0 :(得分:1)

您要找的是a C# equivalent of the C++ friend concept。当你在链接的帖子中读到'最接近的帖子(并且它不是非常接近)是InternalsVisibleTo'(引用Jon Skeet)。但是使用InternalsVisibleTo来完成你想要的东西意味着你必须将你的完整应用程序分解为每个类的库,这可能会创建一个DLL地狱。

基于MattDavey的例子让我:

interface IFocusChecker
{
    bool HasFocus(Control control);
}

class Manager : IFocusChecker
{
    private Control _focusedControl;

    public void SetFocus(Control control)
    {            
        _focusedControl = control;
    }

    public bool HasFocus(Control control)
    {
        return _focusedControl == control;
    }
}

class Control
{
    private IFocusChecker _checker;

    public Control(IFocusChecker checker)
    {
        _checker = checker;
    }

    public bool HasFocus()
    {
        return _checker.HasFocus(this);
    }
}

Control是否具有焦点现在只存储在Manager中,只有Manager可以更改焦点Control

一个小例子如何把事情放在一起,为了完整性:

class Program
{
    static void Main(string[] args)
    {
        Manager manager = new Manager();
        Control firstControl = new Control(manager);
        Control secondControl = new Control(manager);

        // No focus set yet.
        Console.WriteLine(string.Format("firstControl has focus? {0}",
            firstControl.HasFocus()));
        Console.WriteLine(string.Format("secondControl has focus? {0}",
            secondControl.HasFocus()));

        // Focus set to firstControl.
        manager.SetFocus(firstControl);

        Console.WriteLine(string.Format("firstControl has focus? {0}",
            firstControl.HasFocus()));
        Console.WriteLine(string.Format("secondControl has focus? {0}",
            secondControl.HasFocus()));

        // Focus set to firstControl.
        manager.SetFocus(secondControl);

        Console.WriteLine(string.Format("firstControl has focus? {0}",
            firstControl.HasFocus()));
        Console.WriteLine(string.Format("secondControl has focus? {0}",
            secondControl.HasFocus()));
    }
}

答案 1 :(得分:0)

控件本身的变量与其他控件的状态隐含相关可能是一个糟糕的设计决策。 “焦点”的概念在更高层次上受到关注,无论是窗口还是更好的用户(用户是进行聚焦的用户)。因此,应该在窗口或用户级别存储对聚焦控件的引用,但除此之外,还应该有一种方法可以在控件从用户获得/失去焦点时得到通知 - 这可以完成通过用户/经理上的事件或任何标准通知模式。

class Control
{
    public Boolean HasFocus { get; private set; }

    internal void NotifyGainedFocus()
    {
        this.HasFocus = true;
        this.DrawWithNiceBlueShininess = true;
    }

    internal void NotifyLostFocus()
    {
        this.HasFocus = false;
        this.DrawWithNiceBlueShininess = false;
    }
}

class User // or UIManager
{
    public Control FocusedControl { get; private set; }

    public void SetFocusOn(Control control)
    {
        if (control != this.FocusedControl)
        {
            if (this.FocusedControl != null)
                this.FocusedControl.NotifyLostFocus();

            this.FocusedControl = control;

            this.FocusedControl.NotifyGainedFocus();
        }
    }
}

免责声明:我从来没有写过UI库,我可能会说完全废话..