切换状态(C#/Windows 窗体)

发布于 2024-11-15 08:05:24 字数 1682 浏览 0 评论 0原文

所以我认为枚举可以帮助我处理状态。基本上,我有一个小侧边栏应用程序,它有 3 种状态:

最小化 - 您可以在其中看到一个小的彩色矩形面板,指示该应用程序已在桌面上打开。

预览 - 这表明应用程序已打开,您可以看到徽标。

正常 - 可以看到整个侧边栏。

现在,我已经设置了这样的枚举:

public enum CurrentState
{
    Minimized = 0,
    Preview,
    Normal
};

当用户单击始终可见的面板时,我尝试检查 CurrentState 并切换到另一个这样的枚举:

    // If Min=Set(Preview). If Preview=Set(Normal). If Normal=Set(Min).
    if (State.HasFlag(CurrentState.Minimized))
    {
        State = CurrentState.Preview;
        this.Location = new Point(
            Screen.PrimaryScreen.WorkingArea.Right - _minimize.Size.Width - _logo.Size.Width,
            this.Location.Y
        );
    }
    else if (State.HasFlag(CurrentState.Preview))
    {
        State = CurrentState.Normal;
        this.Location = new Point(
            Screen.PrimaryScreen.WorkingArea.Right - this.Size.Width,
            this.Location.Y
        );
    }
    else
    {
        State = CurrentState.Minimized;
        this.Location = new Point(
            Screen.PrimaryScreen.WorkingArea.Right - _minimize.Size.Width,
            this.Location.Y
        );
    }

当应用程序加载时,我将初始值设置为:

CurrentState.Minimized ;,像这样:

CurrentState State = CurrentState.Preview;

所以,这是预期的行为:

如果表单最小化,请将其移动一点,使其处于预览模式。如果它处于预览模式,请将其移动一点,使其处于正常模式。如果是正常模式,请再次将其设置为最小化。

但是,第一次单击始终可见的面板后,它会按预期工作。它将其设置为预览模式并稍微移动了表单。

但是,仅此而已。一旦处于预览模式,第二次单击面板时它不会进入正常模式,这意味着目前无法将其进入正常视图。

我在这里做错了什么吗?

尽管这可能不常见,但这是合乎逻辑的,而且我无法弄清楚哪里出了问题。

这里有一些视觉效果可以帮助更好地阐明我的意思:

在此处输入图像描述

So I thought that an enum would help me with States. Basically, I have a little Sidebar app which has 3 states:

Minimized - Where you can see a small and colored rectangular Panel indicating the app is open on the desktop.

Preview - Which indicated the app is open, and you can see the logo.

Normal - where the whole sidebar can be seen.

Now, I have setup an enum like this:

public enum CurrentState
{
    Minimized = 0,
    Preview,
    Normal
};

And I am trying to check the CurrentState and switch to another like this when the user clicks the always-visible panel:

    // If Min=Set(Preview). If Preview=Set(Normal). If Normal=Set(Min).
    if (State.HasFlag(CurrentState.Minimized))
    {
        State = CurrentState.Preview;
        this.Location = new Point(
            Screen.PrimaryScreen.WorkingArea.Right - _minimize.Size.Width - _logo.Size.Width,
            this.Location.Y
        );
    }
    else if (State.HasFlag(CurrentState.Preview))
    {
        State = CurrentState.Normal;
        this.Location = new Point(
            Screen.PrimaryScreen.WorkingArea.Right - this.Size.Width,
            this.Location.Y
        );
    }
    else
    {
        State = CurrentState.Minimized;
        this.Location = new Point(
            Screen.PrimaryScreen.WorkingArea.Right - _minimize.Size.Width,
            this.Location.Y
        );
    }

And when the application loads, I set the initial value to:

CurrentState.Minimized;, like this:

CurrentState State = CurrentState.Preview;

So, this is the expected behavior:

If form is Minimized, Move it a bit so it is in Preview mode. If it is in Preview, move it a bit so it is in Normal mode. If it is in Normal mode, set it to Minimized again.

But, upon clicking the always-visible panel the first time, it works as expected. It sets it to Preview mode and moved the form a bit.

But, that's as far as it goes. Once it's in Preview mode, it does not go to Normal mode upon clicking the Panel a second time, which means that it's currently impossible to get it to normal view.

Am I doing something wrong here?

Although this may be uncommon, it is logical, and I can't figure out where something is going wrong.

Here's a little visual to help better clarify what I mean:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

因为看清所以看轻 2024-11-22 08:05:24

您拥有的代码始终进入 if/else 结构的最小化分支。

下面的代码不使用标志,而是比较枚举正常工作并按照您想要的方式进展状态:

if (State == CurrentState.Minimized)    
{        
    State = CurrentState.Preview;                        
}    
else if (State == CurrentState.Preview)    
{        
    State = CurrentState.Normal;                        
}    
else    
{        
    State = CurrentState.Minimized;                        
}

不过,有一种想法可能会使此设计更容易使用,那就是实现 状态模式

顾名思义,这种设计模式正是针对您要解决的情况。

本质上,三个状态的逻辑将分为三个单独的对象,这些对象实现类似 IWindowState 的内容,其中 IWindow 状态包含一个名为 MoveState 的方法。当调用 MoveState 时,最小化窗口的状态对象知道下一个状态是预览,并且预览对象知道转到正常。

对于您的情况,这可能是设计过度,但一旦您想要任何更复杂的逻辑,例如“从最小化移动到预览,除非用户有直接移动到正常的设置”,那么该模式在正确管理复杂性方面就值得了。

The code as you have it always enters the Minimized branch of the if/else structure.

The code below that doesn't use the Flags but instead compares the enums works correctly and progresses through the states as you want:

if (State == CurrentState.Minimized)    
{        
    State = CurrentState.Preview;                        
}    
else if (State == CurrentState.Preview)    
{        
    State = CurrentState.Normal;                        
}    
else    
{        
    State = CurrentState.Minimized;                        
}

One thought though, which would probably make this design a lot easier to work with is to implement the State pattern.

As the name suggests, this design pattern deals with exactly the situation you are trying to solve.

Essentially the logic for your three states would get split out into three seperate objects that implement something like IWindowState where IWindow state includes a method called MoveState. When MoveState is called, the state object for a Minimized window knows the next state is Preview, and the Preview object knows to go to Normal.

For your case this might be design overkill, but as soon as you want any more complex logic like "move from minimized to preview unless the user has a setting to move directly to normal" then the pattern pays for itself in properly managing the complexity.

哥,最终变帅啦 2024-11-22 08:05:24

您的问题是HasFlag。您永远不会到达 else 子句,因为您的枚举始终具有最小化标志,即 0。

if 语句中测试相等性: if (State == CurrentState .最小化) ...

Your problem is HasFlag. You are never reaching the else clause becuase your enum ALWAYS has the Minimized Flag which is 0.

Test for equality in your if statements: if (State == CurrentState.Minimized) ...

寻找一个思念的角度 2024-11-22 08:05:24

您错误地使用了 has 标志。 (或者您的枚举是错误的)

如果您使用标志,则枚举应该是

[Flags]
public enum CurrentState
{
    Unknown = 0,
    Minimized = 1,
    Preview = 2,
    Normal = 4
};

关于标志的更全面的文章可以找到此处此处

You are using has flag incorrectly. (Or your enums are wrong)

If you're using flags, the enum should be

[Flags]
public enum CurrentState
{
    Unknown = 0,
    Minimized = 1,
    Preview = 2,
    Normal = 4
};

A more thorough article on flags can be found here and here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文