I'm using Dev Express Ribbon Control to load different views in my WPF Application.
I would like to be able hide/close the Application Menu at run-time when I want, and let the view that needs to be displayed to fit all the size of the screen.
I tried something like this but it didn't work as expected :
this.ApplicationMenu.BackstageClosed += (s, e) =>
{
this.ApplicationMenu
.GetType()
.GetProperty("IsBackStageViewOpen")
.SetValue(this.ApplicationMenu, false);
};
Here's a image of the application, and I'm trying to hide the left Application menu when the view present in the right part is loaded.
I suggest you create an implicit style for the RibbonControl type. In this style, create a trigger for the RibbonControl.ApplicationMenu property and set the RibbonControl.ShowApplicationButton property to false if the menu is empty.
Related
I am using windows form to build an app that draws the form controls based on the connected device dynamically. So I have a tab control and when the user select tab3 for instance the tab page content will be drawing based on connected device for example add two text boxes and a button. How can I do this. I would like also to know how to position those controls after they are created.
private void tabPage3_Click(object sender, EventArgs e)
{
TextBox text = new TextBox();
this.tabPage3.Controls.Add(text);
}
As you just stated, you create your Controls like in your example. Positioning is achieved by the Left and Top Properties of your freshly created control. BUT, my advise is, it will be easier to use predefined UserControls and add them dynamically, because I think you don't have nearly unlimited types of devices.
If you are curious how Visual Studio Designer is creating those code, just look up Designer.cs in InitializeComponent()
For those who are very familiar with C# or VB.NET using the UserControl component in the .NET Framework (which is the hottest framework in my opinion), you were used to adding several buttons that preview different user controls as follows:
1) First you would prepare an appropriate user interface (contains 3 buttons and a single panel on the right area to view each user control after clicking one of the added buttons).
2) Adding 3 user controls from the solution explorer...
3) Inserting the content on each user control...
4) Implementing code for the 3 buttons on the frmMain.cs as the following (for this implementation we will be implementing the "Welcome" button carrying the object name as welcomeBtn, and the rest will have identical code but different user control names instead):
private void welcomeBtn_Click(object sender, EventArgs e)
{
//Clear up everything from the panel if any item exist(s)...
mainPanel.Controls.Clear();
//Create a new instance of a user control for the button...
UserControl1_Welcome welcome = new UserControl1_Welcome();
//Show up the created instance of the user control
mainPanel.Controls.Add(welcome);
}
5) Finally, the program will end up initially like this when running:
http://i.stack.imgur.com/OENwG.png
** Usage of the program **
When you click on the "Welcome" button for example, the result should be expected to be like this:
http://i.stack.imgur.com/iCyo3.png
... and when you click on a different button, lets say "License Agreement" button, you would expect to see something other than your current selection.
MAIN QUESTION
How can we bring the simplicity of Windows Forms in QT CREATOR by applying the "QDockWidget"?
I have tried inserting the QDockWidget component with no problems, but when I try to do the equivalent .NET code for adding the QWidget inside the QDockWidget:
ui->dockWidget->setWidget(myWidget);
which I think is equivalent to this line of code in C#.NET (correct me if I'm wrong here):
ui.Controls.Add(myWidget);
After using this code, my program won't crash nor shows anything running...
P.S. I'm sorry for linking the images, I don't have 10 reputation for making them show up...
What I want is to have a program that does the same thing with the C# example (showing a user control based on the click of a button).
If you want to show a particular widget based on a button click, I suggest to use a QStackedWidget
A simple example would be like this:
// In the constructor of your CustomWidget
// Create your buttons
QPushButton* firstButton = new QPushButton("First Button", this);
QPushButton* secondButton = new QPushButton("Second Button", this);
QPushButton* thirdButton = new QPushButton("Third Button", this);
// Create your (custom) widgets
QLabel* firstPageWidget = new QLabel("First Label", this);
QLabel* secondPageWidget = new QLabel("Second Label", this);
QLabel* thirdPageWidget = new QLabel("Third Label", this);
// Add them to the stackWidget
/*QStackedWidget* */ m_stackedWidget = new QStackedWidget(this);
m_stackedWidget->addWidget(firstPageWidget);
m_stackedWidget->addWidget(secondPageWidget);
m_stackedWidget->addWidget(thirdPageWidget);
// Insert buttons and stackWidget to CustomWidget
QVBoxLayout* layoutStack = new QVBoxLayout();
layoutStack->addWidget(m_stackedWidget);
QVBoxLayout* layoutButtons = new QVBoxLayout();
layoutButtons->addWidget(firstButton);
layoutButtons->addWidget(secondButton);
layoutButtons->addWidget(thirdButton);
QHBoxLayout* layout = new QHBoxLayout();
layout->addLayout(layoutButtons);
layout->addLayout(layoutStack);
setLayout(layout);
// Connect button clicks to slots
connect(firstButton, SIGNAL(clicked()), this, SLOT(onFirstButtonClicked()));
connect(secondButton, SIGNAL(clicked()), this, SLOT(onSecondButtonClicked()));
connect(thirdButton, SIGNAL(clicked()), this, SLOT(onThirdButtonClicked()));
Then you change the currently visible widget in the slots:
void CustomWidget::onFirstButtonClicked() {
m_stackedWidget->setCurrentIndex(0);
}
void CustomWidget::onSecondButtonClicked() {
m_stackedWidget->setCurrentIndex(1);
}
void CustomWidget::onThirdButtonClicked() {
m_stackedWidget->setCurrentIndex(2);
}
Note that if you want the button clicks just to simply change some text (as opposed to change the visible widget), you probably better use a QTextEdit instead of a QStackedWidget, and in the slots call setText("....");
If you have a lot of buttons, you'd better use QSignalMapper to limit the number of slots.
Also, I didn't get why you mentioned QDockWidget since they have a quite specific usage:
The QDockWidget class provides a widget that can be docked inside a QMainWindow or floated as a top-level window on the desktop.
QDockWidget provides the concept of dock widgets, also know as tool palettes or utility windows. Dock windows are secondary windows placed in the dock widget area around the central widget in a QMainWindow.
If you simply want a separate window, you're probably looking for a QDialog
How to do this with QtDesigner:
First you would prepare an appropriate user interface (contains 3 buttons and a single QStackedWidget on the right area to view each user control after clicking one of the added buttons).
Adding 3 pages for the user controls in the stack (+ one for the "empty" page if you really need that). If you want to design the Controls in separate UI Files / Only in Code (instead of all controls in your MainFrame), you would add plain QWidgets and promote them to the appropriate specific widget type
Inserting the content on each user control...
Implementing code for the 3 buttons on the frmMain.cpp/.h as the following (for this implementation we will be implementing the "Welcome" button carrying the object name as welcomeBtn, and the rest will have identical code but different user control names instead):
void FrmMain::on_welcomeBtn_clicked() {
ui->stack->setCurrentWidget(ui->welcomeWidget);
}
Select the "empty" page at as the current page in the designer, so the program will end up initially like this when running: (your screenshot)
When you click on the "Welcome" button for example, the result should be expected to be like this: (your second screenshot)
In my opinion, Miki's answer is the only correct approach to this use case (using a QStackedWidget).
For sake of completeness, I'll demonstrate how the same Clear and Add method as used in .NET is done in Qt:
// Assume controlPanel is a QWidget where you want to place the items
// Assume that controlPanel has set a layout (e.g. QHBoxLayout)
// Clear: Remove all Items from layout
QLayoutItem *child;
while ((child = controlPanel->layout()->takeAt(0)) != NULL) {
delete child;
}
// Now widgets are still there, but not layouted. Delete them explicitly
foreach (QWidget * w, controlPanel->findChildren<QWidget*>()) {
w->deleteLater();
}
// Now controlPanel is cleared
// Add new control
controlPanel->layout()->addWidget(new MyNewControlWidget);
First is, we can not force how other framework works to another one. Each framework has its flow and design.
What I am understand is you want to show another widget to the main window.
If you want to use the QDockWidget, its says on the documentation like this :
void QDockWidget::setWidget(QWidget * widget)
Sets the widget for the dock widget to widget.
If the dock widget is visible when widget is added, you must show() it explicitly.
Note that you must add the layout of the widget before you call this function; if not, the widget will not be visible.
Please share here you code of myWidget, so we can try to help you to figure out what is wrong.
On my side, I can achieve it by add the QVboxLayout on your ui->dockwidget and add QLabel with emtpy string and when you want to show myWidget just call ui->dockwidget->vboxlayout->replaceWidget(label, myWidget);
I want to create simple wizard with 3 pages
Page 1 have just next button
Page 2 have next and previous
Page 3 have previous and finish
I have created the pages and add to them needed buttons and in the events I have call to the next pages, for instance in page one in the button click I added the following code
private void Button_Click(object sender, RoutedEventArgs e)
{
p2 = new Page2();
NavigationService.Navigate(p2);
}
In the main window cs I have changed the inheritance to NavigationWindow instead of Window and in the xaml also. Currently its working but I have 3 questions.
The pages which displayed is part of the main window, how can i avoid it, since when I run it the buttons place is not like I put in the designer? It was changed.
The button currently in the Grid, should I put them in different control (the button place should be like any wizard in the left buttom of the page) ?
How can I avoid the navigation arrows in the page right upper screen?
Thanks!
To answer your questsions in reverse,
3. How can I avoid the navigation arrows in the page upper right screen?
I have an opensource library http://winchrome.codeplex.com/ that re-styles navigation windows in several ways. For example these are all NavigationWindow s
In short you just style the NavigationWindow to only show the parts you want.
2.The button currently in the Grid, should I put them in different control (the button place should be like any wizard in the left buttom of the page) ?
If you look at the styles from WinChrome then you will see that it is just a case of rebuiliding the UI as you want and providing a ContentPresenter to hold your pages. e.g. the VS2012 style applies lots of styles on the window but avoids adding back and forward buttons., whereas the Win7 style rebuilds the back and forwards in a Win7 Style.
If you do this however you will need a means of passing your enabled or visible states to the buttons outside the pages. Take a look at http://www.codeproject.com/Articles/8197/Designer-centric-Wizard-control for how to do this in Winforms. In WPF you could either derive from your Pages to create WizardPage classes with CanBack, CanNext or IsFinish properties, or alteratively define attached properties to do the same (There are examples of how to do this in VS2012.cs where we define the glow color)
And finally
1. The pages which displayed is part of the main window, how can i avoid it, since when I run it the buttons place is not like I put in the designer? It was changed.
I'd need to see some code to comment on how you've done it, but if you look at any of the demo programs in WinChrome then you can see how I've done it without problems.
Good luck!
With the latest (October 2010) WPF Ribbon libraries, there exists a menu item to minimize/maximize (or collapse/expand, if you prefer) the ribbon control.
Does anyone know if there's also a way to hook into the events that control this behaviour so that it could be controlled programmatically from separate UI?
Or, better yet, is there a way to get a collapse/expand button to display in the ribbon like the 2010 Office apps do?
You can use the boolean property IsMinimized on the Ribbon class to show/hide the ribbon itself. It is a dependency property, so you can bind to its value to support the scenarios you describe.
As far as I know, the default template does not have a show/hide button, like Office does, but it shouldn't be too hard to modify the template (using Blend) to add one.
If what you need is know when the bar gets minimized (this happens when you double click a tab header) you could hook to the IsMinimizedChanged event, but er.. it is missing.
Hopefully it is a DependencyProperty so you can successfully hook to any DependencyProperty change this way:
DependencyPropertyDescriptor.FromProperty(Ribbon.IsMinimizedProperty, typeof(Ribbon))
.AddValueChanged(ribbon, (o, args) => /* your code here */);
What I wanted to do (and hence got here) is to prevent it from minimizing when double clicking the header so I ended up using this code:
DependencyPropertyDescriptor.FromProperty(Ribbon.IsMinimizedProperty, typeof(Ribbon))
.AddValueChanged(ribbon, (o, args) => ribbon.IsMinimized = false);
Is not so fancy but gets the job done.
Add a toggle button(simple button and set its content to v or ^ depending upon the operation requested) and then you can use ContentControl in button click to fulfill your requirement:
ContentControl contentControl = FindVisualChildataBankyName<ContentControl>(rbnName, "mainItemsPresenterHost");
contentControl.Visibility = System.Windows.Visibility.Collapsed;
Use contentControl.Visibility = System.Windows.Visibility.Visible; in order to maximize the ribbon
I have asked the question "Is there something like master page in desktop applications?" Now I am in position that I have to extend the question. Thanks for understanding.
I have add one MDI master form into my project and several inherited forms that inherit MDI master one. I was using this code.
private void searchToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form child in this.MdiChildren)
{
child.Close();
}
Search childSearchForm = new Search();
childSearchForm.MdiParent = this;
childSearchForm.Text = "Search ";
childSearchForm.Show();
}
This code is triggered when I press some button on master form and the new in this case Search form is opened inside master.
Now my question is the right way to build desktop applications or there is some other more elegant way where content of user interface can be dynamic and switch from view to view by clicking on the buttons inside. For instance clicking on "Search" button on some search form will take you to search results grid, all that happening in one master form.
And if this is right way (which I doubt) how can I achieve to open other inside forms by clicking on buttons inside them. Also if I put some controls on masterpage they will appear two times in master form and in inherited form.
Thanks.
PS
I am using Visual Studio 2008 and MS SQL 2005.
If you are only wanting to show one view at a time you could create a new user control for each view you require. e.g One for your search results.
Then you could add a panel and clear the controls contained within the panel and add the new one to display the view you are after.
Or as described, the other option is to use a tab control, hide the tabs and set the visible index programatically.
Not sure how you would easily do this in winforms, but in WPF you could create a navigation app - a link driven navigation similar to a web browser experience but still a stand alone application. See http://msdn.microsoft.com/en-us/rampup/cc514215.aspx for details of how to get started.