Как сделать простую гиперссылку в XAML? - PullRequest
51 голосов
/ 10 февраля 2009

Все, что я хочу сделать, это сделать небольшую гиперссылку в XAML. Я перепробовал все. Я сдаюсь.

Какой синтаксис для этого?

<StackPanel Width="70" HorizontalAlignment="Center">

    <Hyperlink Click="buttonClose_Click" Cursor="Hand" 
         Foreground="#555" Width="31" Margin="0 0 0 15"  
         HorizontalAlignment="Right">Close</Hyperlink>

    <Button Width="60" Margin="0 0 0 3">Test 1</Button>
    <Button Width="60" Margin="0 0 0 3">Test 2</Button>
    <Button Width="60" Margin="0 0 0 3">Test 3</Button>
    <Button Width="60" Margin="0 0 0 3">Test 4</Button>
</StackPanel>

Команда Visual Studio: В Visual Studio 2010 я хочу, чтобы Clippy высветился и сказал: «Кажется, вы пытаетесь создать гиперссылку» и скажет мне, как это сделать. Вы не можете сделать это с MEF? Это было бы круто в стиле ретро, ​​и эти маленькие вопросы «как мне сделать то, что я уже знаю, как делать в HTML», сжигают так много времени в процессе обучения с XAML.

Ответы [ 8 ]

168 голосов
/ 10 августа 2009

Вы не можете добавить гиперссылку на StackPanel - вы получите ошибку во время выполнения. (На самом деле, я немного удивлен, что это не ошибка во время компиляции.) Это потому, что Hyperlink не живет на стороне «элементов управления» WPF с <Button> и <StackPanel> и другими вещами, которые размещены на прямоугольных чанках. экрана и спуск с UIElement. Вместо этого он живет в «текстовой» части вещей, с <Bold> и <Run> и <Paragraph> и другими, как правило, текстовыми вещами, которые переносятся по словам и текут в строках и абзацах и спускаются с TextElement.

Как только вы понимаете, что есть две отдельные иерархии классов с различным поведением макета, становится разумным, что гиперссылка будет на «текстовой» стороне вещей (например, легко иметь абзац с гиперссылкой в ​​середине, и даже для этой гиперссылки для переноса через разрыв строки).

Но нет, это не так заметно, когда вы начинаете.

Чтобы смешать два мира и использовать гиперссылку в качестве элемента управления, все, что вам нужно сделать, это поместить его в TextBlock. TextBlock - это элемент управления (то есть может входить в StackPanel), который содержит элементы текста (то есть может содержать гиперссылку):

<TextBlock><Hyperlink Click="buttonClose_Click">Close</Hyperlink></TextBlock>
37 голосов
/ 11 февраля 2009

Вы можете использовать кнопку с пользовательским шаблоном элемента управления, приведенный ниже код является кнопкой с ограниченным стилем гиперссылки (например, она поддерживает только текстовые гиперссылки), но, возможно, она укажет вам правильное направление.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="Link" TargetType="Button">
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Foreground" Value="Blue"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <TextBlock TextDecorations="Underline" 
                    Text="{TemplateBinding Content}"
                    Background="{TemplateBinding Background}"/>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Foreground" Value="Red"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</Page.Resources>
<Button Content="Click Me!" Style="{StaticResource Link}"/>
</Page>
24 голосов
/ 26 ноября 2012

Попробуйте это:

<TextBlock>
    <Hyperlink RequestNavigate="Hyperlink_RequestNavigate" 
               NavigateUri="http://www.msn.com">MSN</Hyperlink> 
</TextBlock>

private void Hyperlink_RequestNavigate(object sender,
                                       System.Windows.Navigation.RequestNavigateEventArgs e)
{
    System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}
5 голосов
/ 20 сентября 2016
<TextBlock>
  <Hyperlink NavigateUri="{Binding YourUri}" RequestNavigate="YourRequestNavigate">
   <TextBlock Text="{Binding YourText}" />
  </Hyperlink>
</TextBlock>

Это свяжет любой связанный текст в вложенном текстовом блоке, я еще не нашел лучшего способа, я хотел бы, чтобы первого текстового блока там не было, если это возможно. Это будет работать и для DataTemplates.

4 голосов
/ 10 августа 2010

Вы можете обнаружить, что если вы привязываетесь к чему-либо, кроме простых текстовых значений, вам нужно будет использовать ContentPresenter, иначе ничего не появится, это может быть правдой, если вы привязываетесь к источнику данных XML.

Триггер свойства для IsMouseOver подчеркивает текст.

Пример, где я привязываюсь к XML, представлен ниже.

<Style x:Key="JobNumberStyleButton" TargetType="{x:Type Button}">
  <Setter Property="VerticalAlignment" Value="Top"/>
  <Setter Property="HorizontalAlignment" Value="Left"/>
  <Setter Property="Cursor" Value="Hand"/>
  <Setter Property="Background" Value="Transparent"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <TextBlock>
          <ContentPresenter
            Margin="0,0,0,0"
            ContentTemplate="{TemplateBinding ContentTemplate}"
            Content="{TemplateBinding Content}"
            ContentStringFormat="{TemplateBinding ContentStringFormat}"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
            RecognizesAccessKey="False"
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </TextBlock>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Button">
            <TextBlock Padding="0,0,0,0" Margin="0,0,0,0">
              <Underline>
                <ContentPresenter
                  Margin="0,0,0,0"
                  ContentTemplate="{TemplateBinding ContentTemplate}"
                  Content="{TemplateBinding Content}"
                  ContentStringFormat="{TemplateBinding ContentStringFormat}"
                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                  RecognizesAccessKey="False"
                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
              </Underline>
            </TextBlock>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Trigger>
  </Style.Triggers>
</Style>
2 голосов
/ 21 декабря 2012

Вы можете просто использовать HyperlinkButton . При нажатии на него в вашем веб-браузере будет отображаться URL:

<HyperlinkButton
    NavigateUri="https://dev.windowsphone.com"
    TargetName="_blank"
    Content="Windows Phone Dev Center" />
1 голос
/ 10 февраля 2009

Обычно значение гиперссылки состоит в том, чтобы дать привязку для отправки пользователя на другую страницу или, вообще говоря, к другому ресурсу, поэтому он реализован таким образом, и вам необходимо указать местоположение для этого ресурса, например:

<HyperLink NavigateUri="http://www.site.com">
   Web Site
</HyperLink>

Тем не менее, я нашел этот блог пост с пользовательским TextBlock, который используется как HyperLink и поддерживает события щелчка.

0 голосов
/ 01 марта 2018

в UWP с mvvmcross я использую это

  <HyperlinkButton Content="{Binding TextSource, ConverterParameter=MyUrl, Converter={StaticResource Language},
           FallbackValue=_MyUrl}" NavigateUri="http://www.google.com" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...