Anders Lindén
Anders Lindén

Reputation: 7303

Trying to pass validation to my custom tooltip control

I am trying to make a custom tooltip control that is used for TextBoxes.

It will look like this:

enter image description here

...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

Answers (1)

Blachshma
Blachshma

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

Related Questions