I am new to WPF, my problem is that I have a top menu as UserControl added in the main window and the main window is split into three columns: in the right most column I have a DockPanel, now my problem is that I don't know how to add another control in that right column when I click on the top menu item.
Some code, to illustrate my attempt:
public partial class TopMenu : UserControl
{
private void menuItem_Click(object sender, RoutedEventArgs e)
{
SecondControl ctrl = new SecondControl();
Window1 winMain = new Window1();
winMain.dp3.Children.Add(ctrl ); // dp3 is the dock panel in the right column of
}
}
Now, what should I do to display that control on window1?
The problem is that you're adding the control to the DockPanel of a new instance of a Window1 window. You will need to 'find' the instance of the Window1 type in which the your TopMenu control is embedded.
Using the code from here we can find the top-level control, your window, and then add the controls to that instance:
private void menuItem_Click(object sender, RoutedEventArgs e)
{
var topLevelControl = GetTopLevelControl(this);
if (topLevelControl != null && topLevelControl is Window1)
{
var currentWindow = topLevelControl as Window1;
SecondControl ctrl = new SecondControl();
currentWindow.dp3.Children.Add(ctrl );
}
}
DependencyObject GetTopLevelControl(DependencyObject control)
{
DependencyObject tmp = control;
DependencyObject parent = null;
while((tmp = VisualTreeHelper.GetParent(tmp)) != null)
{
parent = tmp;
}
return parent;
}
Because you are new to WPF I recommend that you invest some time learning MVVM, binding, INotifyPropertyChanged interface etc.
Good resources are:
NYC DevReady: MVVM - Session 1 (of 5) - Demystifying XAML
NYC DevReady: MVVM - Session 2 (of 5) - Programming with MVVM - Part 1
NYC DevReady: MVVM - Session 3 (of 5) - Programming with MVVM - Part 2
You could solve your problem in multiple ways. For example, you could put ContentControl to the right column where you want to show your SecondControl. Now, when you want to show your SecondControl just fill Content property of the ContentControl with the SecondControl
Related
I have created ribbon form (XtraMain)and I set IsMdiContainer Property to true,i also add documentManager controle i set MdiParent to XtraMain I have add this code to open child forms
public void ViewChildForm(XtraForm _form)
{
if (!IsFormActived(_form))
{
_form.MdiParent = this;
_form.Show();
}
}
private bool IsFormActived(XtraForm form)
{
bool IsOpenend = false;
if (MdiChildren.Count() > 0)
{
foreach (var item in MdiChildren)
{
if (form.Name == item.Name)
{
tabbedView1.ActivateDocument(item);
IsOpenend = true;
}
}
}
return IsOpenend;
}
and i use this code in click of button to open the child form
private void bbtnEmployee_ItemClick(object sender, ItemClickEventArgs e)
{
FrmEmployee frme = new FrmEmployee();
frme.Name = "FrmEmployee";
ViewChildForm(frme);
}
my problem start when the form contain a LayoutControl for example i have this code that open on click of button
private void btnBonLivraison_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
LayoutControl lc = new LayoutControl();
lc.Dock = DockStyle.Top;
LookUpEdit OrderNumber = new LookUpEdit();
OrderNumber.Properties.TextEditStyle = TextEditStyles.DisableTextEditor;
OrderNumber.Properties.DataSource = shippProdu.GetOrderNumber();
OrderNumber.Properties.DisplayMember = "N° Bon de livraison";
OrderNumber.Properties.ValueMember = "N° Bon de livraison";
lc.AddItem(Resources.selectOrderNumber, OrderNumber).TextVisible = true;
lc.Height = 70;
this.Controls.Add(lc);
this.Dock = DockStyle.Top;
lc.BestFit();
the second I click on a button the tabHeader disappears,what cause this problem?and how can I solve it.before I use documentManager I used XtraTabControl and if i click a button to open LayoutControl and after that try to open another form the focus remaining in the first form even when the form two is already opened and if I want to go to form two I must first click on a tab of the first form and then click on tab of the second form , thanks in advance .
this is my main form
and this is when the eader disappears
If DocumentManager resides within the same form to which you add LayoutControl, it is the expected behavior. DocumentManager places a special documents' host onto the main form and set its Dock property to Fill. That is why it is incorrect to place LayoutControl onto the same form and dock it to form edges.
If you need to show tabbed documents and LayoutControl on the same form simultaneously, do not use the MDI mode. Consider the use of a separate UserControl. Place your DocumentManager there. Then, put this UserControl onto your form. Note that in this case UserControl's Dock property should be set to Top or Bottom since LayoutControl should fill all available area or vice versa.
I'm trying to create a custom container as UserControl.
My Goal: I want to be able to drag controls inside the designer and handle incoming controls inside the code of my usercontrol.
Example: I place my container somewhere and then add a button. In this momemt I want my usercontrol to automatically adjust the width and position of this button. Thats the point where Im stuck.
My code:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ContactList : UserControl
{
public ContactList()
{
InitializeComponent();
}
private void ContactList_ControlAdded(object sender, ControlEventArgs e)
{
e.Control.Width = 200; // Nothing happens
e.Control.Height = 100; // Nothing happens
MessageBox.Show("Test"); // Firing when adding a control
}
}
The MessageBox is working well. The set width and height is ignored.
The question is just "why?".
EDIT
I've just noticed, when placing the button and recompiling with F6 the button gets resized to 200x100. Why isnt this working when placing?
I mean... the FlowLayoutPanel handles added controls right when you place it. Thats the exact behaviour im looking for.
Using OnControlAdded
To fix your code, when you drop a control on container and you want to set some properties in OnControlAdded you should set properties using BeginInvoke, this way the size of control will change but the size handles don't update. Then to update the designer, you should notify the designer about changing size of the control, using IComponentChangeService.OnComponentChanged.
Following code executes only when you add a control to the container. After that, it respects to the size which you set for the control using size grab handles. It's suitable for initialization at design-time.
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
if (this.IsHandleCreated)
{
base.BeginInvoke(new Action(() =>
{
e.Control.Size = new Size(100, 100);
var svc = this.GetService(typeof(IComponentChangeService))
as IComponentChangeService;
if (svc != null)
svc.OnComponentChanged(e.Control,
TypeDescriptor.GetProperties(e.Control)["Size"], null, null);
}));
}
}
Hello I'm thinking of creating a tabcontrol which the tabpages will be filtered by the clicks in the menustrip.
For ex.
My menustrip is in form 1
and my tabcontrol is in form 2
My tabcontrol consist of 7 tabs and I want only 1 tab will be shown at a time.
for example If I click the name in the menustrip it will open/show a new form and the tabcontrol will only show the names tab.
I wonder if its possible because making diff forms for each list seems to be very long.
thanks for reading this.
Problem is, the TabPage control has no Visible property (well, it has, but it does nothing). So you can't hide and show tabs at will. You'll have to remove the tabs that should not be visible.
You could make a form (named TabbedForm) with code like this:
private readonly int _index;
public TabbedForm(int index)
{
this._index = index;
InitializeComponent();
}
private void form_Load(object sender, EventArgs e)
{
for (int index = this.tabControl1.TabPages.Count - 1; index >= 0; index--)
{
if (index != this._index)
this.tabControl1.TabPages.Remove(this.tabControl1.TabPages[index]);
}
}
With each menu button (Clicked event) in your main form you can open a TabbedForm with a different index.
Yes, this will work pretty fine. But I think, you must use the default tab view control for this and that must not create the problem either in you case too.
So i'm making a settings screen at the moment where i'll have a tree on the left then a panel on the right. The panel thats on screen will depend on what tree item is selected..
Just wondering how do I go about designing these panels and saving theme for use later on (runtime).
Do I need to go and draw them out etc. view code then copy into a class or something?
Sorry if my question is a bit vague but i'm not really sure what I want :-O
EDIT Yes, i'm looking to make a settings screen like the one found in Visual Studio. A tree on the left (explorer like) and then a new form layout for each tree node.
You'll want to create UserControls instead of a Panel, it is easy to edit in the designer. Dock the tree view to the left and use code like this to select the active user control:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);
}
private UserControl mActivePanel;
void treeView1_AfterSelect(object sender, TreeViewEventArgs e) {
UserControl newPanel = null;
switch (e.Node.Index) {
case 0: newPanel = new UserControl1(); break;
case 1: newPanel = new UserControl2(); break;
// etc...
}
if (newPanel != null) {
if (mActivePanel != null) {
mActivePanel.Dispose();
this.Controls.Remove(mActivePanel);
}
newPanel.Dock = DockStyle.Fill;
this.Controls.Add(newPanel);
this.Controls.SetChildIndex(newPanel, 0);
mActivePanel = newPanel;
}
}
}
Does anyone know a way to open a 2nd form in a .NET application with a certain tab selected in a tab control on that form?
This is what my current code looks like which just opens the form:
SettingsForm TheSettingsForm = new SettingsForm(this);
TheSettingsForm.Show();
SettingsForm.cs is the name of the 2nd form to be opened.
Thanks in advance,
You just need to expose a property on your form that allows the calling code to set the desired tab. You might do it just by index like this:
var form = new SettingsForm(this);
form.SelectedTab = 2;
form.Show();
The property on the form would just set the appropriate property on the tab control:
public int SelectedTab
{
get { return _tabControl.SelectedIndex; }
set { _tabControl.SelectedIndex = value; }
}
Do something like this:
SettingsForm TheSettingsForm = new SettingsForm(this);
TheSettingsForm.TabPanel.SelectedIndex = SettingsFormTabIndexes.MyDesiredTab;
TheSettingsForm.Show();
where you've made a property in TheSettingsForm that exposes the tab control and SettingsFormTabIndexes is a friendly enum naming all the tabs by index.
Add an event handler to the TabControl.SelectedIndexChanged event.
myTabControl.SelectedIndexChanged += myTabControl_SelectedIndexChanged;
private void myTabControl_SelectedIndexChanged(object sender, EventArgs e) {
TabControl tc = sender as TabControl;
if (tc.SelectedIndex == indexOfTabToShowFormOn) {
TheSettingsForm.Show();
}
}