I'm constructing text, and some pieces of the text should contain a hyperlink. However, these hyperlinks do not redirect to a webpage but should open a page in the UWP app (the currently running UWP app, not a new instance of it or a different app).
A HyperlinkButton can only open URL's that lead to an external browser, it can't open a page inside the app.
Using an InlineUIContainer doesn't work, I get
Exception thrown: 'System.ArgumentException' in mscorlib.ni.dll
Additional information: Value does not fall within the expected range.
With this code
List<Inline> ic = new List<Inline>();
InlineUIContainer container = new InlineUIContainer();
TextBlock tbClickable = new TextBlock();
tbClickable.Foreground = new SolidColorBrush(Colors.Red);
tbClickable.Text = label?.name;
tbClickable.Tag = label?.id;
tbClickable.Tapped += TbArtist_Tapped;
container.Child = tbClickable;
ic.Add(container);
When I use
foreach (var item in ic)
{
dTb.Inlines.Add(item);
}
Where tbCurrent is the TextBlock.
Any other ways to get a clickable link as an Inline element?
Best case scenario I can attach a Tapped/Click event handler.
But opening the page via a URI method or so is also good.
I changed to a RichTextBlock and using Blocks I could add a clickable TextBlock.
This works in UWP.
List<Block> ic = new List<Block>();
Paragraph para = new Paragraph();
InlineUIContainer iuic = new InlineUIContainer();
TextBlock hpb = new TextBlock();
hpb.Text = "link text";
hpb.Tag = "some tag to pass on to the click handler";
hpb.Tapped += ClickHandler;
hpb.TextDecorations = TextDecorations.Underline;
hpb.Foreground = new SolidColorBrush((Windows.UI.Color)page.Resources["SystemAccentColor"]);
iuic.Child = hpb;
para.Inlines.Add(iuic);
ic.Add(para);
There is no reason you could not use a HyperlinkButton for this. Quick example:
<HyperlinkButton Click="HyperlinkButton_Click" Content="Click me" />
And the Click handler:
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(MainPage));
}
Related
I have made this in code-behind :
var finishedText = new Run("Some text");
var finishedUrl = new Run("http://somewhere");
var hyperlink = new Hyperlink(finishedUrl) { NavigateUri = new Uri("http://somewhere") };
hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(hyperlink);
FinishedTextBlock.Inlines.Add(Environment.NewLine);
FinishedTextBlock.Inlines.Add(finishedUrl);
In XAML :
<TextBlock Grid.Row="0"
x:Name="FinishedTextBlock"
Width="Auto"
Margin="10 10 0 0">
</TextBlock>
The text is not clickable.
What am I doing wrong?
The text is not clickable.
That is because your Hyperlink text is not even shown. You see the last Run that you have added to the Inlines collection, not the hyperlink itself.
You add the same Run named finishedUrl to your Hyperlink and its containing TextBlock, but you have to create a separate Run instance for the Hyperlink.
var finishedText = new Run("Some text");
var finishedUrl = "http://somewhere";
var finishedUrlRun = new Run(finishedUrl);
var hyperlink = new Hyperlink(finishedUrlRun) { NavigateUri = new Uri("http://somewhere") };
hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(hyperlink);
FinishedTextBlock.Inlines.Add(Environment.NewLine);
var finishedUrlRun1 = new Run(finishedUrl);
FinishedTextBlock.Inlines.Add(finishedUrlRun1);
Even better, just do not add the last Run, as it is redundant, and replace the NewLine with a LineBreak to get the same layout as in your image but with a link.
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(new LineBreak());
FinishedTextBlock.Inlines.Add(hyperlink);
Unless your hyperlink is inside a webview then nothing will happen when you click on a hyperlink.
You need to handle the RequestNavigate event and do something before you'll see a web browser appear with a page in it.
If this was a wpf page inside a frame, or navigationwindow then it would also navigate without code.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.documents.hyperlink?view=netcore-3.1
Remarks
Hyperlink implements the NavigateUri property that you set
with the Uri of the content that should be navigated to when the
Hyperlink is clicked. Hyperlink navigation can only occur, however, if
either the direct or indirect parent of a Hyperlink is a navigation
host, including NavigationWindow, Frame, or any browser that can host
XBAPs (which includes Internet Explorer 6 and later versions, and
Firefox 2.0+). For more information, see the Navigation Hosts topic in
Navigation Overview.
As it is, you need an event handler.
I'm not clear whether you intend the url to appear or a string. If you want a different string then this should work:
TextBlock tb = new TextBlock();
tb.Inlines.Add(new Run {Text="Some text" } );
tb.Inlines.Add(new LineBreak());
Run linkRun = new Run("Link To Google");
Hyperlink hyper = new Hyperlink(linkRun) { NavigateUri = new Uri(#"http://www.google.com") };
hyper.RequestNavigate += (o, e) => Process.Start(new ProcessStartInfo(e.Uri.ToString()){ UseShellExecute = true });
tb.Inlines.Add(hyper);
If you want the url to appear rather than some other string then:
TextBlock tb = new TextBlock();
tb.Inlines.Add(new Run { Text = "Some text" });
tb.Inlines.Add(new LineBreak());
string url = #"http://www.google.com";
Run linkRun = new Run(url);
Hyperlink hyper = new Hyperlink(linkRun){ NavigateUri = new Uri(url) };
hyper.RequestNavigate += (o, e) => Process.Start(new ProcessStartInfo(e.Uri.ToString()) { UseShellExecute = true });
tb.Inlines.Add(hyper);
sp.Children.Add(tb);
Note
One the process start, you will often get an error on win 10 machines without that useshellexecute in the process startinfo.
In older OS ( and you would see in old SO answers ) you used to be able to just process start with a URL and it would work with the default browser.
There is a linebreak inline which is intended to add a linebreak between a series of runs in a textblock.
In XAML, it needs to be like this:
<TextBlock Grid.Row="0"
x:Name="FinishedTextBlock"
Width="Auto"
Margin="10 10 0 0">
<Run Text="Some text" />
<LineBreak/>
<Hyperlink>http://somewhere</Hyperlink>
</TextBlock>
The hyperlink in your code does not content anything. The hyperlink constructor parameter
[finishedUrl] did not initialized the hyperlink to contain the string "http://somewhere".
You can change your code something like below:
var finishedText = new Run("Some text");
var finishedUrl = new Run("http://somewhere");
var hyperlink = new Hyperlink() { NavigateUri = new Uri("http://somewhere") };
hyperlink.Inlines.Add(finishedUrl.Text);
hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
FinishedTextBlock.Inlines.Clear();
FinishedTextBlock.Inlines.Add(finishedText);
FinishedTextBlock.Inlines.Add(Environment.NewLine);
FinishedTextBlock.Inlines.Add(hyperlink);
TextBox x = new TextBox();
x.Height = 30;
x.Width = 200;
x.Name = "Title";
x.Text = item.Title;
x.TextWrapping = TextWrapping.Wrap;
x.FontSize = 60;
StackPanel s = new StackPanel();
s.Children.Add(x);
I have placed this code inside a function called private async void Getnotes();
and im calling this function from the constructor after this.InitializeComponent();
But when i run the app,text boxes are not getting added. what could be the problem?
You need to add the stackpanel to the window
window.AddChild(s);
You need to pass the window to your function.
by default wpf app has a non named grid.
name it "MyMainGrid".
and then you can add ether your stack panel.
MyMainGrid.Children.Add(s);
or directly add textbox to grid.
MyMainGrid.Children.Add(X);
I need to implement printing in my Win 8.1 app and a key requirement is to be able to generate the page after the printer has been selected and the print button has been clicked. This is driven off security requirements around the images and is not negotiable. Eventually this is the point where I'll have to download the images needed in printing.
Currently for my testing I'm using an image that is local to the project:
string testImageLocalSource = "ms-appx:///Assets/testImage.png";
In my test project I'm working in, I'm generating the print page during the PrintDocument.AddPages event handler as follows (layout/margin code removed for succinctness):
private void PrintDocument_AddPages(object sender, AddPagesEventArgs e)
{
var printPageDescription = e.PrintTaskOptions.GetPageDescription(0);
FrameworkElement printPage;
printPage = new MainPrintPage();
// get the printable content
Grid printableArea = (Grid)printPage.FindName("printableArea");
Run myRun1 = new Run();
myRun1.Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
myRun1.FontStyle = Windows.UI.Text.FontStyle.Oblique;
myRun1.Foreground = new SolidColorBrush(Windows.UI.Colors.Purple);
myRun1.FontSize = 42;
Image i = new Image();
i.Source = new BitmapImage(new Uri(testImageLocalSource, UriKind.Absolute));
i.Height = 200;
InlineUIContainer container = new InlineUIContainer();
container.Child = i;
// Create a paragraph and add the content.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(container);
myParagraph.Inlines.Add(myRun1);
// add paragraph to RichTextBlock blocks
var mainRTB = printPage.FindName("mainrtb");
((RichTextBlock)mainRTB).Blocks.Add(myParagraph);
// add page to hidden canvas
printingRoot.Children.Add(printPage);
printingRoot.InvalidateMeasure();
printingRoot.UpdateLayout();
printDocument.AddPage(printPage);
PrintDocument printDoc = (PrintDocument)sender;
printDoc.AddPagesComplete();
}
The text appears fine, and there seems to be extra space where the image should be, but the image doesn't show up.
The image shows up in the print if I use this code in an earlier event handler, such as PrintDocument.Paginate.
Has anybody tried to do something similar and found a solution or else does anybody have an explanation as to what is going on here and an idea on how to remedy it?
UPDATE
I'm attempting to move a bulk of this code to the PrintTask.Submitting event and this is showing promise. I'll update this with an example if it works.
Do you forget to set a width of the image?
i.Width = 200;
Not exactly sure what was causing this in Win 8.1, but it seems to be fixed in Windows 10.
I have a HyperLink control with text in its Text property.
With the following code:
var link = new HyperLink();
var img = new HtmlGenericControl("img");
img.Attributes.Add("src", "text.png");
link.Text = "Test";
link.Controls.Add(img);
When I do this, the image is rendered inside a a tag, but the text is not rendred.
Is there a way to render both the image and the text inside the Text property without throwing a third control in to the mix?
When you put any controls into the WebControl.Controls collection, it will ignore what you have inside Text. So if you want to render both text and other child controls, you should add the text into Controls:
var link = new HyperLink();
var img = new HtmlGenericControl("img");
img.Attributes.Add("src", "text.png");
link.Controls.Add(new Literal{ Text = "Test"}); // this line will add the text
link.Controls.Add(img);
I feel this should work out for you.
var link = new HyperLink();
var img = new HtmlGenericControl("img");
var lbl = new Label();
img.Attributes.Add("src", "text.png");
lbl.Text = "Test";
link.Controls.Add(img);
link.Controls.Add(lbl);
this.Controls.Add(link);
According to the MSDN article "The HyperLink control can be displayed as text or an image." So the answer is no, I'm afraid.
I have a problem, im making me own custom SharePoint webpart.
everything is going well, but the problem is that i can't figure out how to change the location of the textboxes and labels.
anyone knows how i can change the locations?
I am trying to accomplish it in C#.
problem SOLVED.
With the help of component ids. set position of that particular component.
"How to change the location of the textboxes and labels"
In this example i'm using a Button (Action performed on Button Click) and i am also adding how to Generate a TextBox and a Label (When you press this Button).
Just because this is usually a common process within setting locations to a control.
private void button1_Click(object sender, EventArgs e)
{
// Settings to generate a New TextBox
TextBox txt = new TextBox(); // Create the Variable for TextBox
txt.Name = "MyTextBoxID"; // Identify your new TextBox
// Create Variables to Define "X" and "Y" Locations
var txtLocX = txt.Location.X;
var txtLocY = txt.Location.Y;
//Set your TextBox Location Here
txtLocX = 103;
txtLocY = 74;
// This adds a new TextBox
this.Controls.Add(txt);
// Now do the same for Labels
// Settings to generate a New Label
Label lbl = new Label(); // Create the Variable for Label
lbl.Name = "MyNewLabelID"; // Identify your new Label
// Create Variables to Define "X" and "Y" Locations
var lblLocX = lbl.Location.X;
var lblLoxY = lbl.Location.Y;
//Set your Label Location Here
lblLocX = 34;
lblLoxY = 77;
// Adds a new Label
this.Controls.Add(lbl);
}
}
Note: This is just an example and will not work after postback.
I hope this answers to your and everyone's question.