Silverlight DescriptionViewer предотвращает исчезновение всплывающей подсказки при нажатии

Silverlight 4 DescriptionViewer Control отображает Description во всплывающей подсказке:

Синтаксис довольно прост: добавьте пространство имен xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" и следующий XAML в свой UserControl:

<dataInput:DescriptionViewer Description="Some hints on user input etc." />

К сожалению, некоторые пользователи нажимают на отображаемый значок (поскольку он даже парит по умолчанию), который мгновенно закрывает всплывающую подсказку (актуальную и единственную информацию). Хуже того, когда вы нажимаете очень быстро после наведения курсора, всплывающая подсказка вообще не появляется, поэтому пользователь может подумать, что значок вообще не работает.

Я хотел бы предотвратить закрытие всплывающей подсказки при щелчке (просто закройте при «отключении мыши»), даже лучший щелчок должен заставить всплывающую подсказку немедленно отображаться (пропуская обычный тайм-аут перед показом).

Это кажется сложнее, чем я, поскольку нет события OnClick, а также MouseLeftButtonDown, похоже, вообще не срабатывает. Я также попытался переопределить DescriptionViewer Control, но мне не удалось найти подходящие методы для переопределения.

Вы можете помочь? Спасибо!


person thmshd    schedule 29.04.2011    source источник


Ответы (1)


на самом деле это не имеет ничего общего с DescriptionViewer, это поведение всплывающей подсказки. Всплывающая подсказка исчезнет после щелчка мышью. В этом случае вы можете написать собственную всплывающую подсказку.

Я думаю, что обычно, когда вы нажимаете значок DescriptionViewer, должно открываться новое окно, которое похоже на более подробную страницу справки. Чтобы пользователь не запутался.

Обновление:

Вы можете добиться этого, определив присоединенное свойство. По сути, вы прикрепляете это свойство к кнопке внутри вашего DescriptionViewer. Когда запускается событие Click кнопки, вы находите всплывающую подсказку под кнопкой и устанавливаете ее IsOpen в значение ture. Затем вам также необходимо обработать событие MouseLeave, чтобы скрыть всплывающую подсказку, когда ваша мышь отсутствует.

Так определяется прикрепленное свойство.

общедоступный статический класс ButtonAttachedProperties {общедоступный статический логический объект GetOpenToolTip (объект DependencyObject) {return (bool) obj.GetValue (OpenToolTipProperty); }

public static void SetOpenToolTip(DependencyObject obj, bool value)
{
    obj.SetValue(OpenToolTipProperty, value);
}

public static readonly DependencyProperty OpenToolTipProperty =
    DependencyProperty.RegisterAttached("OpenToolTip", typeof(bool), typeof(ButtonAttachedProperties), new PropertyMetadata(false, Callback));


private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var button = d as Button;

    if (button == null || !(bool)e.NewValue) return;

    button.Click += (s, e1) =>
    {
        var tooltip = button.FindName("MyToolTip") as ToolTip;

        if (tooltip != null)
        {
            tooltip.PlacementTarget = button;
            tooltip.IsOpen = true;      
        }
    };

    button.MouseLeave += (s, e2) =>
    {
        var tooltip = button.FindName("MyToolTip") as ToolTip;

        if (tooltip != null)
            tooltip.IsOpen = false;
    };
}

}

Затем в стиле DescriptionViewer вы прикрепляете свойство к кнопке. Также вам необходимо назвать всплывающую подсказку, чтобы ее можно было найти с помощью FindName в классе свойств присоединения.

                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Height="{TemplateBinding Height}" Padding="{TemplateBinding Padding}" Width="{TemplateBinding Width}">
                            <Button x:Name="DescriptionContent" local:ButtonAttachedProperties.OpenToolTip="True" BorderBrush="#FFFFFFFF" BorderThickness="1" Background="#00000000" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" Padding="1" Template="{TemplateBinding GlyphTemplate}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <ToolTipService.ToolTip>
                                    <ToolTip x:Name="MyToolTip" Content="{TemplateBinding Description}" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Style="{TemplateBinding ToolTipStyle}"/>
                                </ToolTipService.ToolTip>
                            </Button>
                        </Border>

Надеюсь это поможет. :)

person Justin XL    schedule 29.04.2011
comment
должно быть открыто новое окно, которое похоже на более подробную страницу справки - да, почему бы и нет, но все же я не могу справиться с щелчком мыши, чтобы сделать это. Похоже, мне нужно написать свой собственный DescriptionViewer. - person thmshd; 01.05.2011
comment
если вам просто нужен щелчок мышью, то это легко. вы можете отредактировать стиль по умолчанию для средства просмотра описания и найти кнопку с именем DescriptionContent внутри шаблона и обработать ее событие Click оттуда. - person Justin XL; 01.05.2011
comment
Хорошо, я понимаю концепцию, лежащую в основе этого, но на самом деле мне не так легко делать это элегантным, многоразовым способом :) - person thmshd; 03.05.2011
comment
да, если вы хотите, чтобы он был универсальным, то это немного больше работы. Пожалуйста, посмотрите мой обновленный ответ. :) - person Justin XL; 03.05.2011
comment
Отлично, сработало! Но не думаете ли вы, что было бы хорошо отказаться от подписки на события Click и MouseLeave? Что вы думаете о подписке на button.Unloaded, изменении событий мыши с лямбда на обычные обработчики и отмене подписки на все три события (Unloaded / Click / MouseLeave) при возникновении button.Unloaded? Хорошая идея? Или есть лучшее место для этого или в этом даже нет необходимости? - person thmshd; 04.05.2011
comment
Привет, так как метод CallBack будет вызываться только один раз, когда вы установите для прикрепленного свойства значение TRUE, два события будут подписаны только один раз. Так что, думаю, в этом нет необходимости. ;) - person Justin XL; 05.05.2011