I&QUOT应该怎样;暂停"该程序显示一个提示给用户? [英] How should I "pause" the program to show a tip to the user?

查看:144
本文介绍了I&QUOT应该怎样;暂停"该程序显示一个提示给用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户正在运行我的第一次节目,我希望他们去通过一系列的技巧。每次他们打了一定的关卡,程序将暂停什么的做的时候,背景会有点模糊(除了尖端参考窗口的区域),前端会出现在上面,解释如何用它/做什么等。

When a user is running my program for the first time, I want them to go through a series of tips. Each time they hit a certain "checkpoint", the program will pause what its doing, the background will go a little fuzzy (except for the area of the window the tip is referencing), and a tip will appear on top, explaining how to use it / what to do etc.

我不很清楚什么是叫这个,在我的脑海其所谓的教程提示,但谷歌搜索与此相关的任何内容都会显示一个与WPF / C#泛型教程的负载。

I dont quite know what to call this, in my head its called "tutorial tips", but googling anything related to this shows a load of generic tutorials with WPF / C#.

什么是做到这一点的最好方法是什么?我真的只是考虑使用弹出窗口,当他们看到controling?有没有更好/更优雅的解决方案,或任何资源在那里与此帮助?

What would be the best way to do this? Am I really just looking at using popups and controling when they are visible? Is there a better / more elegant solution, or any resources out there to aid with this?

推荐答案

好吧,我想我可能有专门太多时间,但它听起来像一个很酷的挑战:p

Ok, I think I may have dedicated too much time to this, but it sounded like a cool challenge :P

我已经创建了一个名为装饰类 TipFocusDecorator 处理这一切。

I've created a Decorator class named TipFocusDecorator that handles all this.

public class TipFocusDecorator : Decorator
{

    public bool IsOpen
    {
        get { return (bool)GetValue(IsOpenProperty); }
        set { SetValue(IsOpenProperty, value); }
    }
    // Using a DependencyProperty as the backing store for Open.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsOpenProperty =
        DependencyProperty.Register("IsOpen", typeof(bool), typeof(TipFocusDecorator), 
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsOpenPropertyChanged));


    public string TipText
    {
        get { return (string)GetValue(TipTextProperty); }
        set { SetValue(TipTextProperty, value); }
    }
    // Using a DependencyProperty as the backing store for TipText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TipTextProperty =
        DependencyProperty.Register("TipText", typeof(string), typeof(TipFocusDecorator), new UIPropertyMetadata(string.Empty));


    public bool HasBeenShown
    {
        get { return (bool)GetValue(HasBeenShownProperty); }
        set { SetValue(HasBeenShownProperty, value); }
    }

    // Using a DependencyProperty as the backing store for HasBeenShown.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HasBeenShownProperty =
        DependencyProperty.Register("HasBeenShown", typeof(bool), typeof(TipFocusDecorator), new UIPropertyMetadata(false));

    private static void IsOpenPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var decorator = sender as TipFocusDecorator;

        if ((bool)e.NewValue)
        {
            if (!decorator.HasBeenShown)
                decorator.HasBeenShown = true;

            decorator.Open();
        }

        if (!(bool)e.NewValue)
        {
            decorator.Close();
        }
    }

    TipFocusAdorner adorner;

    protected void Open()
    {
        adorner = new TipFocusAdorner(this.Child);
        var adornerLayer = AdornerLayer.GetAdornerLayer(this.Child);
        adornerLayer.Add(adorner);

        MessageBox.Show(TipText);  // Change for your custom tip Window
        IsOpen = false;
    }

    protected void Close()
    {
        var adornerLayer = AdornerLayer.GetAdornerLayer(this.Child);
        adornerLayer.Remove(adorner);
        adorner = null;
    }

}

这装饰必须在XAML中使用控制各地要集中。它有三个属性: ISOPEN TipText HasBeenShown ISOPEN 必须设置为真正来使重点和提示窗口显示(并设置为时自动关闭提示窗口)。 TipText 允许您定义必须在提示窗口中显示的文本。和 HasBeenShown 保持的前端窗口是否已示出的轨道,因此,只显示一次。您可以使用绑定所有这些属性或代码隐藏设置。

This Decorator must be used in XAML around the control you want to focus. It has three properties: IsOpen, TipText and HasBeenShown. IsOpen must be set to true to make the focus and tip window appear (and is set to false automatically when the tip window is closed). TipText allows you to define the text that must be shown in the tip window. And HasBeenShown keeps track of whether the tip window has been shown, so it only shows once. You can use Bindings for all these properties or set them from code-behind.

要创建聚焦效果,这个类使用另一个定制装饰器,在 TipFocusAdorner

To create the focus effect, this class uses another custom Adorner, the TipFocusAdorner:

public class TipFocusAdorner : Adorner
{
    public TipFocusAdorner(UIElement adornedElement)
        : base(adornedElement)
    {
    }

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        var root = Window.GetWindow(this);
        var adornerLayer = AdornerLayer.GetAdornerLayer(AdornedElement);
        var presentationSource = PresentationSource.FromVisual(adornerLayer);
        Matrix transformToDevice = presentationSource.CompositionTarget.TransformToDevice;

        var sizeInPixels = transformToDevice.Transform((Vector)adornerLayer.RenderSize);
        RenderTargetBitmap rtb = new RenderTargetBitmap((int)(sizeInPixels.X), (int)(sizeInPixels.Y), 96, 96, PixelFormats.Default);

        var oldEffect = root.Effect;
        var oldVisibility = AdornedElement.Visibility;
        root.Effect = new BlurEffect();
        AdornedElement.SetCurrentValue(FrameworkElement.VisibilityProperty, Visibility.Hidden);
        rtb.Render(root);
        AdornedElement.SetCurrentValue(FrameworkElement.VisibilityProperty, oldVisibility);
        root.Effect = oldEffect;

        drawingContext.DrawImage(rtb, adornerLayer.TransformToVisual(AdornedElement).TransformBounds(new Rect(adornerLayer.RenderSize)));
        drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(22, 0, 0, 0)), null, adornerLayer.TransformToVisual(AdornedElement).TransformBounds(new Rect(adornerLayer.RenderSize)));
        drawingContext.DrawRectangle(new VisualBrush(AdornedElement) { AlignmentX = AlignmentX.Left, TileMode = TileMode.None, Stretch = Stretch.None },
            null,
            AdornedElement.RenderTransform.TransformBounds(new Rect(AdornedElement.RenderSize)));
    }
}

这变暗和模糊(并冻结,因为它实际上使用屏幕捕获)所有的窗口,同时保持期望的控制,突出重点,明确的(和移动 - 即文本框,文本输入光标将仍然可以看到,闪烁)

This dims and blurs (and freezes, since it actually uses a screen capture) all the window, while keeping the desired controls focused and clear (and moving - i.e. in TextBoxes, the text input caret will still be visible and blinking).

要使用此装饰,您只需设置它像这样的XAML:

To use this Decorator, you only must set it like this in XAML:

<StackPanel>
    <local:TipFocusDecorator x:Name="LoginDecorator" 
                             TipText="Enter your username and password and click 'Login'"
                             IsOpen="{Binding ShowLoginTip}">
        <local:LoginForm />
    </local:TipFocusDecorator>
</StackPanel>

和最终的结果,当 ShowLoginTip 是设置为真正

And the final result, when ShowLoginTip is set to true:

已知问题

现在这个使用简单的的MessageBox 显示提示,但你可以创建自己的窗口类的提示,款式呢,只要你想,并与 ShowDialog的调用它( )而不是 MessageBox.Show()(你也可以控制其中窗口出现,如果你希望它出现旁边的集中控制或类似的东西)。

Right now this uses a simple MessageBox to show the tip, but you can create your own Window class for the tips, style it as you want, and call it with ShowDialog() instead of the MessageBox.Show() (and you could also control where the Window appears, if you want it to appear right next to the focused Control or something like that).

此外,这会不会里面的用户控件工作向右走,因为 AdornerLayer.GetAdornerLayer(AdornedElement)将返回里面的用户控件。这可以通过寻找 AdornerLayer 用户控件(或父母的父母的父母很容易解决,递归)。大约有功能这样做。

Also, this won't work inside UserControls right away, because AdornerLayer.GetAdornerLayer(AdornedElement) will return null inside UserControls. This could be easily fixed by looking for the AdornerLayer of the PARENT of the UserControl (or the parent of the parent, recursively). There are functions around to do so.

这不会对网页的工作或者,仅适用于Windows。很简单,因为我使用 Window.GetWindow(本)来获取父窗口的装饰的...你可以使用其他功能得到父,这既可以与Windows,网页或其他工作。由于与 AdornerLayer 的问题,有很多在这里为这个解决方案。

This won't work for Pages either, only for Windows. Simply because I use Window.GetWindow(this) to get the parent Window of the Decorator... You could use other functions to get the parent, that could work either with Windows, Pages or whatever. As with the AdornerLayer problem, there are plenty of solutions for this around here.

另外,我想这可能不知何故动画(使模糊和朦胧的效果逐步显现,例如),但还没有真正看着它...

Also, I guess this could be animated somehow (making the blur and dim effect appear gradually, for instance), but haven't really looked into it...

这篇关于I&QUOT应该怎样;暂停&QUOT;该程序显示一个提示给用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆