Я использовал всплывающую подсказку с поведением. Таким образом, при нажатии на элемент управления появится всплывающая подсказка.

Однако при изменении отключенного элемента управления эта подсказка не появляется. Потому что события мыши не были активированы. Итак, я использовал ContentContorl, и это может быть активировать событие мыши, когда изменение отключено.

Но, когда у меня есть несколько элементов управления в одной сетке, я не знаю, как активировать только один элемент управления.

<Window.Resources>
    <Style TargetType="ContentControl" >
        <Setter Property="localToolTip:ToolTipTouchScreenBehavior.IsEnabled" Value="True"/>
    </Style>
    <Style TargetType="TextBlock" >
        <Setter Property="localToolTip:ToolTipTouchScreenBehavior.IsEnabled" Value="True"/>
    </Style>        
</Window.Resources>

<ContentControl ToolTip="This is ToolTip5 Test.">
            <Grid IsEnabled="False">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="300"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock  HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text="ToolTip Test5"  FontSize="25" 
                            ToolTipService.ShowOnDisabled="True" />
                <TextBox Grid.Column="1" Width="200" />

            </Grid>
</ContentControl>


public class ToolTipTouchScreenBehavior : Behavior<FrameworkElement>
{

    public static DependencyProperty IsEnabledProperty =
        DependencyProperty.RegisterAttached("IsEnabled", typeof(bool),
            typeof(ToolTipTouchScreenBehavior), new FrameworkPropertyMetadata(false, OnIsEnabledChanged));

    public static bool GetIsEnabled(DependencyObject uie)
    {
        return (bool)uie.GetValue(IsEnabledProperty);
    }

    public static void SetIsEnabled(DependencyObject uie, bool value)
    {
        uie.SetValue(IsEnabledProperty, value);
    }

    public static void OnIsEnabledChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e)
    {

        UIElement uie = dpo as UIElement;

        if (uie != null)
        {

            var behColl = Interaction.GetBehaviors(uie);

            var existingBehavior = behColl.FirstOrDefault(b => b.GetType() ==
                  typeof(ToolTipTouchScreenBehavior)) as ToolTipTouchScreenBehavior;

            if ((bool)e.NewValue == false && existingBehavior != null)
                behColl.Remove(existingBehavior);
            else if ((bool)e.NewValue == true && existingBehavior == null)
                behColl.Add(new ToolTipTouchScreenBehavior());

        }

    }

    Timer timer { get; set; }
    ToolTip toolTip { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();

        toolTip = new ToolTip();

        timer = new Timer();
        timer.Interval = 5000;
        timer.Elapsed += OnTimerElapsed;

        AssociatedObject.MouseLeave += OnMouseLeave;
        AssociatedObject.MouseLeftButtonUp += OnMouseLeftButtonUp;

    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.MouseLeave -= OnMouseLeave;
        AssociatedObject.MouseLeftButtonUp -= OnMouseLeftButtonUp;
    }

    public void OnMouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    {
        CloseToolTip();
    }

    public void OnMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        try
        {



            //var temp = AssociatedObject.ToolTip;
            //if (((dynamic)sender).ToolTip != null)
            if (AssociatedObject.ToolTip != null)
            {
                if (AssociatedObject.ToolTip is string)
                    toolTip.Content = AssociatedObject.ToolTip;
                else
                    toolTip = (ToolTip)AssociatedObject.ToolTip;

                //Debug.WriteLine("ToolTip Opened: {0}, ToolTip Value: {1}", toolTip.IsOpen, toolTip.ToolTip);

                toolTip.IsOpen = true;
                timer.Start();

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }



    }

    private void CloseToolTip()
    {

        if (timer.Enabled)
        {
            timer.Stop();
        }

        if (toolTip != null)
        {
            toolTip.IsOpen = false;
        }
    }

    private void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        Application.Current.Dispatcher.BeginInvoke((Action)CloseToolTip, DispatcherPriority.Send);
    }

}

Когда у меня есть код выше, я просто хочу добавить всплывающую подсказку только для TextBlock. не TextBox.

Как применить всплывающую подсказку только к одному специальному элементу управления?

0
Song 3 Апр 2017 в 12:57

2 ответа

Лучший ответ

Если вы хотите реагировать на взаимодействие с мышью для отключенного элемента, вы можете добавить визуальный элемент к слою adorner (который останется включенным для отключенного базового элемента) и захватить ввод там. Ниже приведен лишь грубый набросок с Adorner, который выполняет произвольное действие с MouseLeftButtonUp только для отключенных элементов управления, и с прикрепленным свойством, чтобы подключить Adorner к некоторому элементу Framework (вместо этого вы можете использовать свое поведение).

public class DisabledMouseUpAdorner : Adorner
{
    private Border _Child;
    private Action _OnDisabledMouseUp;

    public DisabledMouseUpAdorner(FrameworkElement element, Action onDisabledMouseUp)
        : base(element)
    {
        _OnDisabledMouseUp = onDisabledMouseUp;
        _Child = new Border();
        _Child.MouseLeftButtonUp += Adorner_Click;
        // actually you probably want an invisible adorner, but for demonstration lets add some color
        //_Child.Background = new SolidColorBrush(Colors.Transparent);
        _Child.Background = new SolidColorBrush(new Color() { A = 20, R = 255, G = 0, B = 0 });
        _Child.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
        _Child.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
        _Child.IsHitTestVisible = !element.IsEnabled;
        element.IsEnabledChanged += Adorned_IsEnabledChanged;
        AddVisualChild(_Child);
    }


    void Adorned_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        _Child.IsHitTestVisible = !AdornedElement.IsEnabled;
    }


    void Adorner_Click(object sender, RoutedEventArgs e)
    {
        if (_OnDisabledMouseUp != null)
        {
            _OnDisabledMouseUp();
        }
    }


    protected override int VisualChildrenCount
    { get { return 1; } }


    protected override Visual GetVisualChild(int index)
    {
        if (index != 0) throw new ArgumentOutOfRangeException();
        return _Child;
    }


    protected override Size MeasureOverride(Size constraint)
    {
        _Child.Measure(constraint);
        return base.MeasureOverride(constraint);
    }


    protected override Size ArrangeOverride(Size finalSize)
    {
        _Child.Arrange(new Rect(new Point(0, 0), finalSize));
        return finalSize;
    }
}



public static class Attached
{
    public static bool GetToolTipOnClickEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(ToolTipOnClickEnabledProperty);
    }

    public static void SetToolTipOnClickEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(ToolTipOnClickEnabledProperty, value);
    }

    // Using a DependencyProperty as the backing store for ToolTipOnClickEnabled.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ToolTipOnClickEnabledProperty =
        DependencyProperty.RegisterAttached("ToolTipOnClickEnabled", typeof(bool), typeof(Attached), new PropertyMetadata(false, new PropertyChangedCallback(OnToolTipOnClickChanged)));

    private static void OnToolTipOnClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = d as FrameworkElement;

        if (element != null)
        {
            if (element.IsLoaded)
            {
                if ((bool)e.NewValue == true)
                {
                    AddOverlay(element);
                }
                else
                {
                    RemoveOverlay(element);
                }
            }
            else
            {
                element.Loaded -= Element_Loaded;
                element.Loaded += Element_Loaded;
            }
        }
    }

    private static void Element_Loaded(object sender, RoutedEventArgs e)
    {
        var elem = sender as FrameworkElement;
        elem.Loaded -= Element_Loaded;
        if (GetToolTipOnClickEnabled(elem))
        {
            AddOverlay(elem);
        }
        else
        {
            RemoveOverlay(elem);
        }
    }

    private static void RemoveOverlay(FrameworkElement element)
    {
        var adl = AdornerLayer.GetAdornerLayer(element);
        var ad = adl.GetAdorners(element);
        foreach (var item in ad)
        {
            if (item is DisabledMouseUpAdorner) adl.Remove(item);
        }
    }

    private static void AddOverlay(FrameworkElement element)
    {
        var a = AdornerLayer.GetAdornerLayer(element);
        if (a != null)
        {
            a.Add(new DisabledMouseUpAdorner(element, () => ClickHandler(element)));
        }
        else
        {
        }
    }

    // whatever you actually want to do when the adorner triggers
    private static void ClickHandler(FrameworkElement element)
    {
        if (element.ToolTip == null)
        {
            return;
        }
        var tt = element.ToolTip as ToolTip ?? new ToolTip() { Content = element.ToolTip, StaysOpen = false };
        tt.IsOpen = true;
    }
}

Использование

<TextBlock Text="ToolTip Test5"  FontSize="25"
    ToolTip="Shows on click when disabled"
    local:Attached.ToolTipOnClickEnabled="True" />
0
grek40 3 Апр 2017 в 11:00

Если ваша проблема такая же, как упомянуто grek40 , ответом будет следующее:

Если вы хотите, чтобы подсказка отображалась, когда родительский элемент управления отключен, вы можете установить для свойства ToolTipService.ShowOnDisabled значение true. WPF 2000things

0
Manjunatha K B 3 Апр 2017 в 10:49