5

在我的程序中,我有三种不同的 UI 状态(正常、成功和错误),并且在每一种状态中,控件都是可见/隐藏、启用/禁用、颜色变化、标签表示不同的东西……等等。在我的代码隐藏中,我基本上希望能够说 ChangeWindowState(UI.Normal);

所以我的问题是如何最好地实现每个状态的控制更改?

当然,我可以手动更改代码隐藏中的控件,但我想知道是否有更好的方法使用 wpf 主题或样式。然后也许我可以将窗口设置为使用我预先定义的“错误”主题。我目前并不真正理解它们,所以我可能使用错误的术语,但如果有人能指出我正确的方向如何最好地做这样的事情,我将不胜感激。

谢谢!

4

3 回答 3

5

当然,有很多方法可以解决这个问题。如果您有一个程序状态“对象模型”,您可以使用 DataTemplates 和 DataTriggers 的某种组合。假设情况并非如此,这是另一种方法:您引用了一个窗口,因此假设您在窗口类中定义了一个“依赖属性”,如下所示:

public partial class Window1 : Window
{
    public Window1()
    {
        this.InitializeComponent();

        // Insert code required on object creation below this point.
    }

    public ProgramStatus ProgramStatus
    {
        get { return (ProgramStatus)GetValue(ProgramStatusProperty); }
        set { SetValue(ProgramStatusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ProgramStatus.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ProgramStatusProperty =
        DependencyProperty.Register("ProgramStatus", typeof(ProgramStatus), typeof(Window1), new UIPropertyMetadata(null));
}

public enum ProgramStatus
{
    Normal,
    Success,
    Error
}

现在,您可以通过直接绑定或触发器来更改窗口的任何元素(包括窗口本身)的几乎任何属性。这是通过属性触发器更改窗口背景颜色的示例:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:Test"
    x:Class="Test.Window1"
    x:Name="Window"
    Title="Window1"
    Width="640" Height="480">
    <Window.Style>
        <Style TargetType="{x:Type l:Window1}">
            <Style.Triggers>
                <Trigger Property="ProgramStatus">
                    <Trigger.Value>
                        <l:ProgramStatus>Error</l:ProgramStatus>
                    </Trigger.Value>
                    <Setter Property="Background" Value="Red" />
                </Trigger>
                <Trigger Property="ProgramStatus">
                    <Trigger.Value>
                        <l:ProgramStatus>Normal</l:ProgramStatus>
                    </Trigger.Value>
                    <Setter Property="Background" Value="Blue" />
                </Trigger>
                <Trigger Property="ProgramStatus">
                    <Trigger.Value>
                        <l:ProgramStatus>Success</l:ProgramStatus>
                    </Trigger.Value>
                    <Setter Property="Background" Value="Green" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Style>
    <Grid x:Name="LayoutRoot"/>
</Window>
于 2009-04-05T23:11:44.333 回答
3

另一个选项可能是作为 WPFToolkit 的一部分发布的 VisualStateManager。

更多信息是通过这些链接:

祝你好运。

于 2009-04-07T14:48:08.830 回答
1

对于这类事情,我几乎总是使用“UpdateUI()”函数。此函数查看模型/成员属性/状态的状态并启用/禁用、隐藏/显示等。试图将这段代码传播出去总是会导致问题(所以“ChangeWindowsState(..)”实际上只是设置了一个属性,然后调用了“UpdateUI()”)。

我已经看到了一些以通用方式处理此问题的尝试……但没有一个是我真正喜欢的(例如 WTL 的东西)。一般来说,这些实施得并不差……但很容易迅速超越他们的能力。通常,状态逻辑非常重要,使用简单的 if/then/else 样式逻辑对其进行显式编码会减少混乱(维护、调试等)。

于 2009-04-05T22:51:32.400 回答