If you were changing attributes of a single control I would say create a reusable Behaviour and attach that to the TextBlock control.
As you want to introduce an extra control, use a custom control in place of your TextBlock (not add a button to the TextBlock).
- Create a custom user control.
- Add a TextBlock and Button to it inside the standard LayoutRoot grid it creates.
- Edit the settings so that the button is initially hidden. e.g. Opacity=0
- Expose the TextBlock Text as a dependency property to allow normal binding to the content.
- Expose the button click as an event to allow outside users top catch the event
- Add ShowButton and HideButton storyboards to show and hide the button. Do this by altering the opacity value. If a button is completely transparent you cannot click it.
If you need specific help on how to do any of these steps, just ask. You can also contact us via our website.
*Note: Using Expression Blend for this type of work is 100 times easier than in VS 2010. Too many programmers ignore Blend as a design tool only. It is well worth the effort learning.
@Tai: As you asked nicely via email, here is a complete example of the sort of user control with dependency property for the text and event for the button. You can use this as a guide. I have stripped it down to the bare minimum:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="SilverlightApplication1.TextButtonControl"
mc:Ignorable="d"
d:DesignHeight="20" d:DesignWidth="200">
<UserControl.Resources>
<Storyboard x:Name="ShowButtonStoryboard">
<DoubleAnimation Duration="0:0:0.5" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ActionButton" d:IsOptimized="True"/>
</Storyboard>
<Storyboard x:Name="HideShowButtonStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ActionButton">
<SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeave">
<ei:ControlStoryboardAction Storyboard="{StaticResource HideShowButtonStoryboard}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseEnter">
<ei:ControlStoryboardAction Storyboard="{StaticResource ShowButtonStoryboard}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBlock x:Name="DisplayTextBlock" TextWrapping="Wrap" Text="TextBlock" d:LayoutOverrides="Height"/>
<Button x:Name="ActionButton" Content="..." Grid.Column="1" Opacity="0"/>
</Grid>
</UserControl>
And the code-behind:
using System;
using System.Windows;
using System.Windows.Controls;
namespace SilverlightApplication1
{
public partial class TextButtonControl : UserControl
{
public event EventHandler<RoutedEventArgs> ButtonClicked;
public string Text
{
get { return (string)GetValue(TextProperty); }
set
{
SetValue(TextProperty, value);
DisplayTextBlock.Text = value;
}
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text",
typeof(string),
typeof(TextButtonControl),
new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnTextChanged)));
static void OnTextChanged(object sender, DependencyPropertyChangedEventArgs args)
{
// If you need to know about text changes...
}
public TextButtonControl()
{
InitializeComponent();
this.ActionButton.Click +=new RoutedEventHandler(ActionButton_Click);
}
private void ActionButton_Click(object sender, RoutedEventArgs e)
{
if (ButtonClicked != null)
{
ButtonClicked(this, e);
}
}
}
}