WPF에서의 하이퍼링크 사용 예시
WPF 응용 프로그램에 하이퍼링크를 추가할 수 있는 몇 가지 제안을 보았습니다.Hyperlink
통제.
코드로 사용하는 방법은 다음과 같습니다.
<Window
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"
mc:Ignorable="d"
x:Class="BookmarkWizV2.InfoPanels.Windows.UrlProperties"
Title="UrlProperties" Height="754" Width="576">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid>
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.RowSpan="2">
<StackPanel >
<DockPanel LastChildFill="True" Margin="0,5">
<TextBlock Text="Url:" Margin="5"
DockPanel.Dock="Left" VerticalAlignment="Center"/>
<TextBox Width="Auto">
<Hyperlink NavigateUri="http://www.google.co.in">
Click here
</Hyperlink>
</TextBox>
</DockPanel >
</StackPanel>
</ScrollViewer>
</Grid>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Margin="0,7,2,7" Grid.Row="1" >
<Button Margin="0,0,10,0">
<TextBlock Text="Accept" Margin="15,3" />
</Button>
<Button Margin="0,0,10,0">
<TextBlock Text="Cancel" Margin="15,3" />
</Button>
</StackPanel>
</Grid>
</Window>
다음의 에러가 표시됩니다.
속성 'Text'는 'Hyperlink' 형식의 값을 지원하지 않습니다.
내가 뭘 잘못하고 있지?
응용 프로그램이 웹 브라우저에서 링크를 열도록 하려면 매개 변수로 주소를 사용하여 웹 브라우저를 프로그래밍 방식으로 여는 함수에 RequestNavigate 이벤트를 설정한 HyperLink를 추가해야 합니다.
<TextBlock>
<Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate">
Click here
</Hyperlink>
</TextBlock>
코드 배후에 RequestNavigate 이벤트를 처리하려면 다음과 같은 내용을 추가해야 합니다.
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
// for .NET Core you need to add UseShellExecute = true
// see https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.useshellexecute#property-value
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
또한 다음과 같은 Import도 필요합니다.
using System.Diagnostics;
using System.Windows.Navigation;
어플리케이션에서는 다음과 같이 표시됩니다.
Fuji의 응답에 가세해, 부속의 속성으로 재사용할 수 있습니다.
public static class HyperlinkExtensions
{
public static bool GetIsExternal(DependencyObject obj)
{
return (bool)obj.GetValue(IsExternalProperty);
}
public static void SetIsExternal(DependencyObject obj, bool value)
{
obj.SetValue(IsExternalProperty, value);
}
public static readonly DependencyProperty IsExternalProperty =
DependencyProperty.RegisterAttached("IsExternal", typeof(bool), typeof(HyperlinkExtensions), new UIPropertyMetadata(false, OnIsExternalChanged));
private static void OnIsExternalChanged(object sender, DependencyPropertyChangedEventArgs args)
{
var hyperlink = sender as Hyperlink;
if ((bool)args.NewValue)
hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
else
hyperlink.RequestNavigate -= Hyperlink_RequestNavigate;
}
private static void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
}
그리고 이렇게 사용하세요.
<TextBlock>
<Hyperlink NavigateUri="https://stackoverflow.com"
custom:HyperlinkExtensions.IsExternal="true">
Click here
</Hyperlink>
</TextBlock>
나중에 문자열을 현지화하려면 이 답변만으로는 충분하지 않습니다.다음과 같은 것을 권장합니다.
<TextBlock>
<Hyperlink NavigateUri="https://speechcentral.net/">
<Hyperlink.Inlines>
<Run Text="Click here"/>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
Hyperlink
컨트롤이 아니라 흐름 콘텐츠 요소이며 흐름 콘텐츠를 지원하는 컨트롤에서만 사용할 수 있습니다.TextBlock
.TextBoxes
일반 텍스트만 있습니다.
주의해 주세요.Hyperlink
를 항법용으로 사용할 필요는 없습니다.명령어에 연결할 수 있습니다.
예를 들어 다음과 같습니다.
<TextBlock>
<Hyperlink Command="{Binding ClearCommand}">Clear</Hyperlink>
</TextBlock>
IMHO의 가장 간단한 방법은 새로운 제어를 사용하는 것입니다.Hyperlink
:
/// <summary>
/// Opens <see cref="Hyperlink.NavigateUri"/> in a default system browser
/// </summary>
public class ExternalBrowserHyperlink : Hyperlink
{
public ExternalBrowserHyperlink()
{
RequestNavigate += OnRequestNavigate;
}
private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
}
이 질문에 답을 썼는데 문제가 생겼어요.
예외 반환:{"The system cannot find the file specified."}
좀 더 조사해보니.WPF 어플리케이션이 CORE인 경우는, 이 설정을 변경할 필요가 있습니다.UseShellExecute
로.true
.
이것은, Microsoft 의 문서에 기재되어 있습니다.
프로세스를 시작할 때 셸을 사용해야 하는 경우 true, 실행 파일에서 직접 프로세스를 생성해야 하는 경우 false입니다.기본값은 true 입니다.NET Framework 앱 및 false on.NET Core 앱
따라서 이 작업을 수행하려면 다음과 같이 추가해야 합니다.UseShellExecute
로 설정합니다.true
:
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri){ UseShellExecute = true });
재사용 가능한 핸들러에 대한 아더의 아이디어는 좋았지만, 더 간단한 방법이 있을 것 같습니다.
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
if (sender.GetType() != typeof (Hyperlink))
return;
string link = ((Hyperlink) sender).NavigateUri.ToString();
Process.Start(link);
}
모든 종류의 프로세스를 시작하면 보안상의 위험이 있을 수 있으므로 주의해 주십시오.
내 생각에 가장 아름다운 방법 중 하나는 행동을 사용하는 것이다.
필요한 것은 다음과 같습니다.
- nuget 의존관계:
Microsoft.Xaml.Behaviors.Wpf
- 이미 기본 제공 행동이 있는 경우 Microsoft 블로그에 있는 이 가이드를 따라야 할 수 있습니다.
xaml 코드:
xmlns:Interactions="http://schemas.microsoft.com/xaml/behaviors"
그리고.
<Hyperlink NavigateUri="{Binding Path=Link}">
<Interactions:Interaction.Behaviors>
<behaviours:HyperlinkOpenBehaviour ConfirmNavigation="True"/>
</Interactions:Interaction.Behaviors>
<Hyperlink.Inlines>
<Run Text="{Binding Path=Link}"/>
</Hyperlink.Inlines>
</Hyperlink>
동작 코드:
using System.Windows;
using System.Windows.Documents;
using System.Windows.Navigation;
using Microsoft.Xaml.Behaviors;
namespace YourNameSpace
{
public class HyperlinkOpenBehaviour : Behavior<Hyperlink>
{
public static readonly DependencyProperty ConfirmNavigationProperty = DependencyProperty.Register(
nameof(ConfirmNavigation), typeof(bool), typeof(HyperlinkOpenBehaviour), new PropertyMetadata(default(bool)));
public bool ConfirmNavigation
{
get { return (bool) GetValue(ConfirmNavigationProperty); }
set { SetValue(ConfirmNavigationProperty, value); }
}
/// <inheritdoc />
protected override void OnAttached()
{
this.AssociatedObject.RequestNavigate += NavigationRequested;
this.AssociatedObject.Unloaded += AssociatedObjectOnUnloaded;
base.OnAttached();
}
private void AssociatedObjectOnUnloaded(object sender, RoutedEventArgs e)
{
this.AssociatedObject.Unloaded -= AssociatedObjectOnUnloaded;
this.AssociatedObject.RequestNavigate -= NavigationRequested;
}
private void NavigationRequested(object sender, RequestNavigateEventArgs e)
{
if (!ConfirmNavigation || MessageBox.Show("Are you sure?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
OpenUrl();
}
e.Handled = true;
}
private void OpenUrl()
{
// Process.Start(new ProcessStartInfo(AssociatedObject.NavigateUri.AbsoluteUri));
MessageBox.Show($"Opening {AssociatedObject.NavigateUri}");
}
/// <inheritdoc />
protected override void OnDetaching()
{
this.AssociatedObject.RequestNavigate -= NavigationRequested;
base.OnDetaching();
}
}
}
이것도 누군가에게 도움이 되길 바랍니다.
using System.Diagnostics;
using System.Windows.Documents;
namespace Helpers.Controls
{
public class HyperlinkEx : Hyperlink
{
protected override void OnClick()
{
base.OnClick();
Process p = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = this.NavigateUri.AbsoluteUri
}
};
p.Start();
}
}
}
언급URL : https://stackoverflow.com/questions/10238694/example-using-hyperlink-in-wpf
'programing' 카테고리의 다른 글
T-SQL에서 Date Time 필드를 업데이트하려면 어떻게 해야 합니까? (0) | 2023.04.10 |
---|---|
'git reset --hard HEAD'를 사용하여 이전 커밋으로 되돌리려면 어떻게 해야 합니까? (0) | 2023.04.10 |
'\r': 명령어를 찾을 수 없습니다 - .syslogrc / .syslog_profile (0) | 2023.04.10 |
64비트 Windows에서 64비트 DLL이 System32로, 32비트 DLL이 SysWW64로 이동하는 이유는 무엇입니까? (0) | 2023.04.10 |
Linux에서 특정 텍스트(문자열)가 포함된 모든 파일을 찾는 방법 (0) | 2023.04.10 |