Silverlight: make a hyperlink button appear like a textblock?
I'm trying to make all the words in textblock that are URIs clickable. Here is the approach I've taken:
private static void onTextChanged(DependencyObject dependObj, DependencyPropertyChangedEventArgs e)
{
WrapPanel wrapPanel = ((HyperlinkTextBlock)dependObj).LayoutRoot;
wrapPanel.Children.Clear();
// TODO: use a real wordbreaker?
// adding an extra space to the end of the last word. Cry.
IList<string> words = ((string)e.NewValue).Split(' ').Select(word => word + " ").ToList();
foreach (string word in words)
{
Uri uri;
if (Uri.TryCreate(word, UriKind.Absolute, out uri))
{
// TODO the style is off - the text is too big
wrapPanel.Children.Add(new HyperlinkButton()
{
Content = word,
NavigateUri = uri,
TargetName = "_blank",
Margin = new Thickness(0),
Padding = new Thickness(0),
});
}
else
{
wrapPanel.Children.Ad开发者_开发技巧d(new TextBlock() { Text = word, TextWrapping = TextWrapping.Wrap });
}
}
}
(I'd be totally up for a more XAML-oriented/declarative way of doing this, but I'm not sure how I'd go about doing that.)
This works fine (except it'd be nice to use a real wordbreaker), except that the HyperlinkButton
looks funny. It is too large, and the text won't wrap. It also seems to have some offset, which I've tried to fix through setting the Margin
and Padding
to 0, but it hasn't solved the problem.
Any other ideas? Really, I want HyperlinkText
instead of HyperlinkButton
, but I don't think that Silverlight 3 for the Windows Phone 7 offers that.
Here's a solution I came up with by extracting the style for the hyperlink button and then making modifications to the areas that I cared about (that odd indent as you mentioned). That way the behaviour is exactly the same except for the things you want to change.
When you create the hyperlink button also set the style property as shown below:
var button = new HyperlinkButton
{
...
Style = (Style) Resources["HyperlinkButtonWithNoIndent"]
};
Then in your page, add the following style to the resources:
<Style x:Key="HyperlinkButtonWithNoIndent" TargetType="HyperlinkButton">
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<Border Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TextElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="TextElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<TextBlock x:Name="TextElement" Text="{TemplateBinding Content}" TextDecorations="Underline" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I've never tried to do this with a TextBlock
but it works with Image
and StackPanel
so it should work in your case too. Add a handler for the Tap
gesture to your TextBlock
and listen for it. Then, in the event handler, you can navigate to the URL.
TextBlock MyTextBlock = new TextBlock() { Text = "Tap Me!" };
GestureListener listener = GestureService.GetGestureListener( MyTextBlock );
listener.Tap += new EventHandler<GestureEventArgs>( OnMyTextBlockTapped );
And the event handler looks like this:
void OnMyTextBlockTapped( object sender, GestureEventArgs e )
{
// Navigate to URL
}
You could even animate the tap by starting a Storyboard
in the event handler and performing the navigation when the animation completes.
Have you tried retemplating the control in blend? You should be in complete control of the presentation styling there for all consituent parts that make up the HyperlinkButton.
- Rclick the control
- Edit Template
- Edit a Copy
- Format away
You can reuse the resulting styling.
精彩评论