WP7 - ContextMenu doesn't show on Hyperlink - c#

I'm trying to programmatically add a ContextMenu to a Hyperlink. I've searched in the documentation and in forums, and seems that the correct solution should be this:
var link = new Hyperlink();
link.Inlines.Add(new Run() { Text = linkText });
link.FontWeight = FontWeights.Bold;
link.TargetName = linkText;
link.Click += new RoutedEventHandler(link_Click);
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem();
item.Click += new RoutedEventHandler(CopyLink);
item.Header = "copy link";
item.Tag = linkText;
menu.Items.Add(item);
ContextMenuService.SetContextMenu(link, menu);
This code compiles and does not throw any exception. I've tested and the ContextMenu is indeed added to the Hyperlink. The problem is that it will not show anytime. I can tap & hold the link all the time of the world and the menu will not appear. Also tried to add a listener with GestureService and GestureListener, but the Hold event does not fire at all.
Anyone can help me? Thanks.

You can't do ContextMenus on Hyperlinks. You can do it on a HyperlinkButton, though. I'm not exactly sure of the reason, but it does work. Depending on what you're trying to do, HyperlinkButton may have been what you wanted anyway (Hyperlink is usually only used inside documents of text).

I just found the answer while reading the Windows Phone 7.5 Unleashed book by Daniel Vaughan. My problem was that I needed to add a hyperlink in a RichTextBox, and I can only use Inlines to show text. Hyperlink is an Inline, but does not support ContextMenu. As Tim suggested, I needed to use HyperlinkButton. The solution is that there is a class called InlineUIContainer. So, this
var inline = new InlineUIContainer { Child = SomeHyperlinkButton }
made the trick for me.

Related

Insert action link into text in WPF Label

I have a WPF app i'm working on.
There is a label on my window I use as a status window that I manage with a singleton.
How do i insert a link into that that label?
All the answers I see on this have to do with changing the XAML or the nature of the label. These solutions don't work, because literally anything can appear in this status window.
I want the link to raise a custom event when clicked.
Does anyone know how to do this?
Example of how the text uploaded to the label should operate. I need to raise an event when the hypertext formatted word is clicked:
"Inserting a link into text" is the same thing as adding a Hyperlink to the Inlines collection of a TextBlock:
TextBlock tb = new TextBlock();
var hp = new Hyperlink(new Run("error"));
hp.Click += (s, e) => { /* do something */ };
tb.Inlines.Add(new Run("There was as an "));
tb.Inlines.Add(hp);
tb.Inlines.Add(new Run(" on run"));
This is the one and only way to do this in WPF and it is very simple.

Attempting to get child control of currently selected tab

I'm attempting to get the TextEditor control off of the currently selected tab in my tab control. The tabs and text editors are created dynamically so simply referencing the text editor isn't an option. I've searched far and wide and so far, no answer has helped me.
The following code works for Winforms, but not WPF:
var currentTextEdit = tabControl.SelectedTab.Controls.OfType<TextEditor>().First();
Is there something along these lines that perhaps I'm missing?
This is how I'm creating each tab and adding a TextEditor control to each tab created:
TabControl itemsTab = (TabControl)this.FindName("tabControl");
TextEditor textEdit = new TextEditor();
Then to create the new tab and add the text editor:
TabItem newTab = new TabItem();
newTab.Content = textEdit;
itemsTab.Items.Add(newTab);
Further down in the code I get the currently selected tab like so:
TabItem ti = tabControl.SelectedItems as TabItem;
And using the GetChildOfType extension method, I'm attempting to get the current text editor like so:
var currentTextEditor = ti.GetChildOfType<TextEditor>();
This code returns the NullReferenceException:
File.WriteAllText(saveF.FileName, currentTextEditor.Text);
Indeed I wrote a not right thing in my comment. TabControl works in a little different way in comparing with other controls. It has a collection of TabItems. TabControl can show every header of each TabItem which belongs to its collection.
At the same time TabControl "grabs" the selected TabItem's content and add it to its ContentPresenter (it is called PART_SelectedContentHost - just use ILSpy).
So, returning to your issue, you have to search for your TextEditor directly in the TabControl. Then you can use this code:
TabControl itemsTab = (TabControl)FindName("tabControl");
TextEditor currentTextEditor = itemsTab.GetChildOfType<TextEditor>();
if (currentTextEditor != null)
{
File.WriteAllText(saveF.FileName, currentTextEditor.Text);
}
You should always check if the object you obtain from GetChildOfType<T> method is not null, since if GetChildOfType<T> cannot find a control whose type is T, it returns null.
As I told in my previous comment you can find here the code of GetChildOfType<T>.
I hope this answer can help you.
When working with WPF I usually use the method
var currentTextEdit = tabControl.SelectedTab.Children.OfType<TextEditor>().First();

IBeam caret on contextmenu of RichTextBox

I create a contextmenu and add this to a richtextbox. Now when I Right Click on the richtextbox, the contextmenu appears, but the cursors is an IBeam caret and not the default arrow.
Does anybody know how to fix this?
var tb = new RichTextBox();
tb.Text = "test";
var items = new[] {new MenuItem("Save",SaveTextFile)};
var ctxMenu = new ContextMenu(items);
tb.ContextMenu = ctxMenu;
Thanks,
Erik
I'm dreadfully sorry, but there is no way to fix this. It has been an issue with Winforms for a long time. See here and here.
Microsoft promised to look into it, but apparently they haven't fixed it yet.

Tab control like chrome browser in Silverlight Application

I have seen this one before. We want a dedicated tab item with a '+' symbol on it. Like chrome browser in Silver light Application.
There is always a tab item appears at the end half visible and once you click on it, it turns into a complete tab item.
That was a little though to answer :P
Here it goes:
Create a class called LinqToVisualTree. You can find it at the end of this post, along with an explanation of what it does. Basically, it lets you query your Visual Tree through LINQ.
To add anything to the tabs row in a TabControl, you need to manipulate the TabPanel, which holds the "buttons" of tabs. TabPanel is in the System.Windows.Controls.Primitives namespace, so refer to it.
The easiest way to get the TabPanel I've found is to name at least one of your TabItems and do this:
using System.Windows.Controls.Primitives; // Contains TabPanel
using LinqToVisualTree;
void AddPlusButton() {
// Creates a button beside the tabs
var button = new Button()
{
Content = "+",
IsTabStop = false // To prevent keyboard press
};
// Links the Click with the "new tab" function
button.Click += new RoutedEventHandler(btPlus_Click);
// *** HERE IS THE TRICK ***
// Gets the parent TabPanel in the Visual Tree and cast it
var tabpn = tabItem1.Ancestors<TabPanel>().FirstOrDefault() as TabPanel;
// Links the button created
tabpn.Children.Add(button);
}
Here's the method for the plus button:
void btPlus_Click(object sender, RoutedEventArgs e)
{
// Creates a new TabItem
var ti = new TabItem();
ti.Header = "TabAdded";
ti.Content = new TextBlock() { Text = "Tab content!" };
// Links it
tabControl.Items.Add(ti);
}
That's it! Tip: I've just find out about the TabPanel class using Silverlight Spy. Searching on Google, I could just find methods of doing this by changing the Template Style from the TabControl.
Best regards!

Adding controls to TabItems dynamically at runtime in C#

So, here is my issue, im working in a Wpf application, so i dont have all of the standard windows form controls.. so im attempting to use a windowsformshost, to hold a webbrowser inside of a tabitem. So here is what i have:
Tab t = new Tab();
Browser newbrowse = new Browser(t);
WindowsFormsHost host = new WindowsFormsHost();
Grid g = new Grid();
host.Child = newbrowse;
newbrowse.Dock = DockStyle.Fill;
g.Children.Add(host);
t.Header = "New Tab";
t.Content = g;
tabControl1.Items.Add(t);
now, Tab, and Browser, are just my custom implementations of the controls, and they both are tested and working. So that is not the issue. Now as far as i can see, that code should work. But I'm left staring at a blank tab page. Note that this will need to be in the codebehind and cant be included in the WPF itself.
Thanks for any input! :) Cheers
EDIT: Note that i have also tried the operation with the standard, controls.tabitem, and forms.webbrowser to the same effect
I just tried this, and apparently what breaks your plan is the line:
newbrowse.Dock = DockStyle.Fill;
Comment it out, and watch how it suddenly works!

Categories