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();
Related
How can I change the Combobox list to always appear above the ComboBox object using C# only (no XML)?
The property DropDownStyle doesn't seem to be available in this case.
First of all, note that DropDownStyle is only available for a Windows Forms ComboBox, not a WPF ComboBox.
So, you need to go about this in a different way with WPF. Basically, WPF uses styles and templates to determine the visual aspects of a control.
For this particular problem, your going to need to edit the Placement property of the ComboBox's Popup control, which is part of its ControlTemplate.
Here is an example of how you could do this (put this in the code-behind):
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
// create a combo box
var comboBox = new ComboBox
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Width = 200
};
// add some items
comboBox.Items.Add(new ComboBoxItem { Content = "Apple" });
comboBox.Items.Add(new ComboBoxItem { Content = "Banana" });
comboBox.Items.Add(new ComboBoxItem { Content = "Orange" });
// add the combo box to your window
AddChild(comboBox);
// apply the control template
comboBox.ApplyTemplate();
// obtain the popup (which is named "PART_Popup") from the control template
var controlTemplate = comboBox.Template;
var popup = (Popup)controlTemplate.FindName("PART_Popup", comboBox);
// set the placement of the popup
if (popup != null) popup.Placement = PlacementMode.Top;
}
Final point: How did I know that there was a Popup called "PART_Popup"? There are a couple ways:
You can use Visual Studio designer to actually generate a copy of the standard control template for any built-in control. Specifically, place a control (e.g., a ComboBox) in your window, go to Document Outline, right click the ComboBox, and select "Edit Template...".
You can use the Snoop utility to actually see the "visual tree" of controls/graphics in your window.
i'm using telerik control.
So i want to ask,
In winforms application ,Is it possible to add more than one panel in same location and display one at a time just like show/hide property.
Make sure you have placed all panel control in same container or form. then you can use Visible property to show and hide panel. BringFront and SendToBack function will be used to bring panel on top or send it to back. If you have placed any panel in another panel then that will be disappeared when you Hide parent panel. So, Make sure all panels' parent control must be same. To determine the parent control simply select that panel and press escape key to select their parent.
private void LoadPanels()
{
panel1.Location = new Point(10,10);
panel2.Location = new Point(10,10);
panel3.Location = new Point(10,10);
panel4.Location = new Point(10,10);
panel5.Location = new Point(10,10);
VisiblePanel("panel1");
}
private void VisiblePanel(string panelName)
{
string[] panels = new string[]{"panel1","panel2","panel3","panel4","panel5"};
for (int i=0;i<panels.Length;i++)
this.Controls[panels[i]].Visible = (panels[i] == panelName);
this.Controls[panelName].BringToFront(); //Not required you can remove this line.
}
Here's a slightly different approach you might want to consider...
Are you wanting to be able to programmatically select the contents of a rectangular area at runtime, selecting among various controls to display? If so, you could use a custom TabControl which has its tabs (not the pages) hidden.
Then you can select which page is displayed by programmatically changing its SelectedIndex property at runtime.
Doing it like this means that your form editor will show a normal tab control, which allows you to much more easily add the content to each page - but at runtime the tabs will be hidden from the user; they will just see the contents of the currently selected page.
See Hans Passant's answer here for how to create such a custom tab control.
(However, you might also want to override the OnKeyDown for the custom tab control in order to ignore Ctrl-Tab.)
I searched the internet for this but i couldn't find how to do it with C#
What i am trying to do is make it so that when i click on my NewTab button, a new tab appears with the same controls that were on the first tab. I saw some information on how to add a UserControl to your form, but C# doesn't have anything like that.
And for everyone who would say "Post your code", i don't have any, so don't bother saying that, the only code i have is the code for the program and that wouldn't help anyone.
EDIT
I have rewritten my solution to use reflection.
using System.Reflection;
// your TabControl will be defined in your designer
TabControl tc;
// as will your original TabPage
TabPage tpOld = tc.SelectedTab;
TabPage tpNew = new TabPage();
foreach(Control c in tpOld.Controls)
{
Control cNew = (Control) Activator.CreateInstance(c.GetType());
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(c);
foreach (PropertyDescriptor entry in pdc)
{
object val = entry.GetValue(c);
entry.SetValue(cNew, val);
}
// add control to new TabPage
tpNew.Controls.Add(cNew);
}
tc.TabPages.Add(tpNew);
Some information can be found here.
http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows-Forms
Your best bet would be to look at this article:
Code Project
Then apply the following code to add the cloned control (this would be in your button click handler code (based on article):
private void button1_Click(object sender, EventArgs e)
{
// create new tab
TabPage tp = new TabPage();
// iterate through each control and clone it
foreach (Control c in this.tabControl1.TabPages[0].Controls)
{
// clone control (this references the code project download ControlFactory.cs)
Control ctrl = CtrlCloneTst.ControlFactory.CloneCtrl(c);
// now add it to the new tab
tp.Controls.Add(ctrl);
// set bounds to size and position
ctrl.SetBounds(c.Bounds.X, c.Bounds.Y, c.Bounds.Width, c.Bounds.Height);
}
// now add tab page
this.tabControl1.TabPages.Add(tp);
}
Then you would need to hook the event handlers up. Will have to think about this.
I know it's an old thread but I just figured out a way for myself and thought I should share it. It's really simple and tested in .Net 4.6.
Please note that this solution does not actually create new controls, just re-assigns them all to new TabPage, so you have to use AddRange each time you change tabs. New tab will show the exact same controls, content and values included.
// Create an array and copy controls from first tab to it.
Array tabLayout = new Control [numberOfControls];
YourTabControl.TabPages[0].Controls.CopyTo(tabLayout, 0);
// AddRange each time you change a tab.
YourTabControl.TabPages[newTabIndex].Controls.AddRange((Control[])tabLayout);
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.
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!