I'm kind of standing on a pipe (if that saying works as it does in german) with my current problem.
I would like to create a Windows Store app which uses the GroupedItemsPage as kind of a main Menu with each tile navigating to a new page/part of the application.
Now all Tutorials/Examples I found are using the GroupItemsPage to display the same kind of content. So each tile is of the same kind of datatype and mostly stored in a list or something.
The step between coming from a background where I would love to simply create each tile by doing something like SettingsPage mySettingsPage = new SettingsPage(); and adding that to the right View to something different is difficult right now.
The only idea I would have right now to fill my GroupedItemsPage would be to create a new DataSource of a generic Type and add each and every single page to this DataSource, but that seems strange to me ...
What's the best practice here?
Use this:
https://skydrive.live.com/?cid=3a5ca8204ec61147&id=3A5CA8204EC61147%2135841&authkey=!AAOLlNWZh4K-FkQ
to main page add this in xaml:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.DefaultViewModel["Groups"] = e.Parameter;
}
and copy from this project classes to your project.
Related
I have a problem with my project. Since I do not like it that every Windows Form is a new window I did try to use an different way.
This way I did create an FormGUI which contains the menu and calls the different UserControls. Since we did only learn how to use Windows Forms I do know how to work with them. There I would have changed the constructor of the new Windows Form to pass Data.
But this time I use mainly one Windows Form and different UserControls.
e.g. I have one to add new data, an other one to show data in a datagrid and one to show the data inside of an chart. At least this is the result.
But I do not finde a way to transport informations from the Windows Form into one User Control and how to get them back. In order to use this knowlegde somewhere else.
Does someone knew a tutorial where I can see how it could work? Or could explain it to me.
Since the UI is part of the end project that will be marked I would prefer my new way. But if I can't find a work around I will need to change it so that I would work with different windows form. >_> But really... I do not want the application to open new windows for every task. I would prefer to only show the information in one page.
In my search I did found some tutorials about UI Design with Windows Form but only the design (where a chart would be placed it is only a picture) an not how this will work with real informations.
I hope you could understand my problem...
Let's assume that the constructor of the form is something like this
private List<MyData> _data;
public MyForm(List<MyData> data)
(
...
_data = data;
)
Declare an interface
public IDataAware
{
List<MyData> Data { get; set; }
}
and let the user controls implement it. E.g.
public MyDataGridUserControl : UserControl
{
...
public List<MyData> Data {
get { return (List<MyData>)dataGridView1.DataSource; }
set { dataGridView1.DataSource = value }
}
}
If you are working with a BindingSource, access the BindingSource instead of the grid control. Now, you can access all your user controls through the same interface. In the form you can create a field
private IDataAware _dataUserControl;
In a menu item click routine, you could do some thing like this
_dataUserControl = new MyDataGridUserControl();
in another one
_dataUserControl = new MyChartUserControl();
But all the user controls implementing IDataAware you can do
Controls.Add(_dataUserControl);
_dataUserControl.Data = _data;
Note: Forms, Controls and UserControls are just classes as any other class, and you can do all the object-oriented things with them as with any c# class. (There are some restrictions with generics, however.)
Currently I'm creating a really big project in Visual Studio 2012, where there are some common settings for each form ("Cancel" and "Save" buttons, Methods that change in every form but have the same name, font sizes and types, form color etc.) it will save me a lot of time if I could do all the design a single windows form and when I edit or modify it, have the changes reflected in the other forms as well.
Let's say I need 10 forms, to create them I would choose this default format and have my menu and basic objects already placed and designed; then after 10 forms I decided to move a button a bit, but don't want to go to every form and move it; just change it in the original format, refresh and all my forms will have that button in the new location.
I used Templates as recommended by Can one set the default properties for new WinForms created in Visual Studio?. But I still have the issue that if I change something in the template it won't refresh in every other form created with the template to that point.
I've already thought of changing the InitializeComponent in the WinForm default format, but this is not recommended and I wouldn't want any errors from this later on.
Any ideas?
Thanks in advance
Inheritance will work for your solution.
Create "base" form with all "common" controls
Create new "derived" form and change form to inherit from your "base" form.
If you have some common logic in base form, which need to be "overridden" in derived forms - put it to the virtual method
// Base form
protected virtual void Close()
{
// Base logic
}
private void CloseButton_Click(object sender, EventArgs e)
{
Close();
}
// In derived form - just override "Close" method
protected override void Close()
{
// custom logic - will be executed when "Close" button clicked
}
In base form leave empty space for custom controls. Because you will not be able access baseform controls through designer in derived form.
Another approach - Model-View-ViewModel(MVVM)
- Introduce own UserControl with common controls(view) which have property - instance of ViewModel.(Viewmodel will contains behaviour logic and possibility to change "base" settings.)
- Add this user control to all "derived" forms and set UserControl.ViewModelProperty to instance which will represent logic for this particular form.
Without knowing "full" context of your goals - difficult to suggest more, but I am pretty sure you can build maintainable relations between forms, which can share common logic and view.
No, there is nothing you can do. Once you use a template to create a project or a file, it becomes a one-off. You have to edit it manually, or use a text editor that is powerful enough to employ a find and replace with pattern matching and capture group insertion.
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 need to build some kind of phone emulator to test our webservice and have a general idea how the flow will go.
Doesn't needs to be anything fancy.
Now I made a WPF form with a phone image in it. In the display of the phone I have placed a frame. That looks good so far :)
But what now? How can I fill the frame with say the startscreen? Do I need to create a usercontrol for each page I want to view or show? Or is there another approach?
And how about databinding? I want to use MVVM, so I need to create a viewmodel for each usercontrol like we do normally? Or a viewmodel for each page?
I just discovered the WPF Frame Control and it seems there's not so much info on the net to find, or not what I want.
Thx for any pointers in the right direction.
Here is an image how it now looks:
For each view (screen) that the end user is going to see you will need to make a page that will hold all your logic and functions per page. All you do in Cycle through the pages in your own way.
FrameName.Navigate(PageName);
Remember to initialize the pages before you can use them. You can intialize them when you use the Navigate function like:
FrameName.Navigate(new PageName());
This works well for smaller projets, bigger projects you might want to use some clever way of initializing the pages because you navigate, like:
if(TimeToLoadPage == True)
{
PageName pagename = new PageName();
RunPageNavigation()
}
public Void RunPageNavigation()
{
FrameName.Navigate(pagename);
}
You can data bind the width and height of the page by inheriting from the Frame (Going through Ancestry route). You can do all the content based stuff in a page exactly the same as a window. You can't however control the page like a window.
Hope this helps a bit more.
In my MainPage.xaml, I created a Pivot Control: <controls:Pivot Title="Powder God" Name="PivotControl">.
My first pivot view is a HubTile that summarize all other individual pages. So my application bar will be different between the first pivot view and all other ones.
That's why I put my application bar in App.xaml's resource section, then load based on selected index of my pivot.
My question is:
In the application bar I will be using for all individual pages, I want to have a delete option, where I will remove that specific item (a view model) from my data context.
I know I can use PhoneApplicationFrame root = Application.Current.RootVisual as PhoneApplicationFrame; to access navigation services, but I don't know how can I reference to my pivot, so that I can get the selected index and proceed forward.
Thanks!
Using MVVM you SHOULDN'T do this:
((PageType)Application.Current.RootVisual).PivotControl. //Blah
PageType is whatever type PhoneApplicationFrame is that contains your PivotControl. If this doesn't work you need a Property in the RootVisual
PAGE
public Pivot MyPivot
{
get
{
return PivotControl;
}
}
APP
((PageType)RootVisual).MyPivot. //Blah
On one level Microsoft's suggestion of putting the ApplicationBar in App.xaml is great as it can be referenced from everywhere and would appear to encourage code reuse: however this question highlights the limit to this approach. An application bar is typically used to provide actions which are specific to the current page (or pivot item) and just because the buttons are the same you may not want the exact same code to run in each case.
In this case I think it would better to create a factory method that creates your common ApplicationBar with the click handlers you specify specific to your page/pivot item. For bonus points put the method in a new class (not App) so it doesn't get lost in all the boilerplate code there. Call this factory method in your page constructor and remember your ApplicationBar in your class. For multiple app bars, create them all up front and you can then easily switch between these app bars in your Pivot SelectionChanged code.
The alternative of creating the ApplicationBar in App.xaml and then retrieving this from the App.xaml.cs "Resources" ResourceDictionary in code, modifying the click callbacks, is more complicated in my opinion.
I wish they'd done a better job of implementing the ApplicationBar so people wouldn't want to do this. I've found that using the ApplicationBar forces you to add code to your Page.xaml.cs even if you use a framework like MVVM Light. This is still OK in MVVM as it's UI specific code that belongs in the View, but it makes things inconsistent if you're using ICommand everywhere else. Last time I decided it was better to create the entire ApplicationBar in code rather than hack this kind of thing via App.xaml.cs.
Update: There is a UserVoice request for a data bindable ApplicationBar.