Reputation: 7303
I am trying to make a custom tooltip control that is used for TextBoxes.
It will look like this:
...except for some pixels that comes from the background components that I have gimped away as good as possible.
The idea comes from: How to implement Balloon message in a WPF application
The problem is that the code behind of my custom control never gets the validation object (that should be passed to it via the trigger in generic.xaml).
Why not?
generic.xaml:
<Style TargetType="{x:Type TextBox}" x:Name="tb">
<Setter Property="Width" Value="200" />
<Setter Property="Background" Value="{StaticResource InputBackgroundColor}" />
<Setter Property="BorderBrush" Value="{StaticResource InputBorderBrush}" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Margin" Value="5,0,0,5" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip">
<Setter.Value>
<Windows:ValidationBalloonPopupWindow
Validation="{Binding Path=Validation, ElementName=tb}" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
As you see, I try to refer to Validation by using ElementName of tb. Seems like Name is not used in templates. If I change to x:Key instead, all my textboxes becomes like 10 pixels wide. Probably not the right thing to do in other words.
The code behind, ValidationBalloonPopupWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
namespace Foo.ToolTips
{
public partial class ValidationBalloonPopupWindow : ToolTip
{
public ValidationBalloonPopupWindow()
{
InitializeComponent();
}
public static DependencyProperty ValidationProperty
= DependencyProperty.Register("Validation", typeof(object), typeof(ValidationBalloonPopupWindow),
new PropertyMetadata(null, OnChangedValidationByBinding));
private static void OnChangedValidationByBinding
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ValidationBalloonPopupWindow)d).OnChangedValidationByBinding(e.NewValue);
}
public void OnChangedValidationByBinding(object newValue)
{
txtMessage.Text = newValue.GetType().Name;
}
private object _validation;
public object Validation
{
get
{
return _validation;
}
set
{
_validation = value;
txtMessage.Text = _validation.GetType().Name;
}
}
}
}
Which has a setter that should run, I have tried to put a lot of breakpoints in this file without success.
The xaml for the control itself, ValidationBalloonPopupWindow.xaml:
<ToolTip x:Class="FRAM.Windows.ValidationBalloonPopupWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent" BorderBrush="Transparent" HasDropShadow="false"
Placement="Bottom"
Height="Auto" Width="Auto">
<Grid Height="126" Width="453">
<Border Margin="7,13,0,0"
CornerRadius="10,10,10,10" Grid.ColumnSpan="4" HorizontalAlignment="Left" Width="429" Height="82" VerticalAlignment="Top" Grid.RowSpan="2">
<Border.Effect>
<DropShadowEffect Color="#FF474747" />
</Border.Effect>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF58C2FF" Offset="0" />
<GradientStop Color="#FFFFFFFF" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<StackPanel Orientation="Vertical">
<Label Content="Title" Height="31" HorizontalAlignment="Left"
Margin="12,8,0,0" Name="lblCaption" FontSize="16" FontWeight="Bold" />
<TextBlock Margin="18,0,0,0" Name="txtMessage" Width="378" HorizontalAlignment="Left">Body</TextBlock>
</StackPanel>
</Border>
<Path Data="M25,25L10.9919,0.64 0.7,25" Fill="#FF58C2FF" HorizontalAlignment="Left"
Margin="32,3,0,0" Stretch="Fill" Width="22" Height="10" VerticalAlignment="Top" />
</Grid>
</ToolTip>
Upvotes: 2
Views: 717
Reputation: 17385
Instead of referring by name, get the Textbox itself by using RelativeSource
binding.
Try something like this:
<Setter Property="ToolTip">
<Setter.Value>
<Windows:ValidationBalloonPopupWindow
Validation="{Binding RelativeSource={RelativeSource Self}, Path=Validation}" />
</Setter.Value>
</Setter>
Upvotes: 2