我使用了带有行为的工具提示。因此,当单击控件时,将显示工具提示。
但是,当更改禁用控件时,不会出现此工具提示。 因为,鼠标事件未激活。因此,我使用了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);
}
}
当我有上面的代码时,我只想添加ToolTip只用于TextBlock。不是TextBox。
如何将ToolTip仅应用于一个特殊控件?
答案 0 :(得分:0)
如果您的问题与 grek40 提到的问题相同,那么以下是答案:
如果您确实希望在禁用父控件时显示工具提示,则可以将ToolTipService.ShowOnDisabled属性设置为true。 WPF 2000things
答案 1 :(得分:0)
如果要对禁用的元素进行鼠标交互作出反应,可以向装饰图层添加视觉效果(对于已禁用的基础元素将保持启用状态)并在此处捕获输入。以下只是一个粗略的草图,其中一个Adorner仅在MouseLeftButtonUp
对禁用的控件执行任意操作,并在附加属性上将adorner连接到某个框架元素(您可能希望利用您的行为)。
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" />