What is the difference between a ContextMenu class and the Popup class?
The MSDN docs do a nice job of displaying the distinction:
The Popup Class:
Represents a pop-up window that has
content.
The ContextMenu Class:
Represents a pop-up menu that enables
a control to expose functionality that
is specific to the context of the
control.
So the ContextMenu is a more-specific version of a Popup - it's meant to be bound to a specific control, providing ways to interact with that control. Read further on the MSDN page: the ContextMenu has built-in facilities for displaying itself when you right-click on the associated control, and it is automatically displayed within a Popup.
The Popup class is much more general: it simply defines a barebones window (no default borders or decoration) that can display any arbitrary UIElement on top of other controls (notice that the Popup class is part of the Primitives namespace, meaning it's meant to be part of the composition of other controls, such as the ContextMenu).
Related
I'm on writing a simple application, it has a menu and when user choices each MenuItem, i want to change my window's content to display the selected content.
i have two option to that.
i can add a <Frame></Frame> to my window and write some pages.
i can write some UserControls and put them in a ContentControl
as user fires MenuItem click event.
so I'm confused to select the right choice for this purpose.
Navigation can be succefully implemented by using Frame/Pages or ContentControl/Views. It is a matter of choice.
However, Frame/Page have some gotchas, e.g. page.DataContext not inherited from parent Frame?
If you don't need isolation specifically, then stick to ContentControl. Navigation in prism framework is built with regions which are located in different type of controls (e.g. ContentControl, TabControl), not Frame (see docs)
one more approach for simple navigation is ViewModel based.
Examples:
WPF MVVM navigate views
Navigation with MVVM by Rachel Lim (external)
I have a MainWindow in my WPF app.
This MainWindow has a menu on the left and when a menu option is selected a UserControl is loaded on the right.
This is similar to Master Pages in asp.net
What I want to do now is to have a modal window show from the UserControl which will only allow the user to interact with the modal window.
I have seen examples of the Main Window showing a modal window (http://www.codeproject.com/Articles/36516/WPF-Modal-Dialog) but not sure on how to load this from a UserControl.
There's this: dialogs and mvvm but this is the best example I've seen of dealing with it: mvvm and closing forms
The first link I've not used and stumbled across while looking for the second link to post that here. The second link has two downloads, you can ignore the _service download, it's basically the same.
One way in WPF is this method
Add a new Window to the project.
Add other controls onto the window as needed.
In XAML name the window such as x:Name="MyWindow"
Put on Dependency properties on the window and have each of the controls bind to the window's data context such as {Binding MyText, ElementName=MyWindow}. (Note I still use, even for WPF these Visual Studio code snippets to add different dependency properties, these save time for a very redundant operations of adding them: Silverlight Snippets.
In the location where you want to launch the model dialog use this example:
Example:
var about = new About(); // Create the new window
// I've added a CompanyName dependency property.
about.CompanyName = "OmegaMan Industries";
about.ShowDialog();
I'd like to create a CustomWindow class that behaves this way:
1. Non-client area of window is utilized too, TabControl's tabs are present instead of window title like in Google Chrome.
2. Tabs are right-padded so when window is too small, min/max/close buttons don't collide with tabs - this should be doable in TabControl template.
3. There is a button after tabs much like a "new tab" button in Google Chrome. Again, this should be doable with custom implementation of TabControl and creating a fake child for rendering I guess.
4. My class inherits from Window class and every child in children collection is mapped to a TabControl tab like if TabControl.ItemsSource was bound to Window.Children.
5. Window exposes property ItemsSource that behaves like children collection too.
6. Window offers a way to style what TabControl recognizes as ItemTemplate. When I feed the window like CustomWindow.ItemsSource = new string[] { "a", "b", "c" }; and I populate a template for items, three tabs will be created where tab header style is hardcoded in CustomWindow class and tab item content area is templated by user.
As you can see this is basically a outline of Google Chrome window which is exactly what I am trying to accomplish. I know how to bend window's chrome the way I want with everything like system menu, double-click maximizing etc. handled. But I don't know how to make inherited class from Window that will force it's only child to be a TabControl of my choice (tabs headers are styled) but in reality it's child collection will be TabControls child collection. I am not as much experienced with WPF as I'd like and I want to start this the right way so I don't need to rewrite it in future.
Additionaly, when this is resolved, I want to give user the way to tell the tab it's pinned, which I guess is best accomplished by defining an attached property in CustomWindow, something like CustomWindow.IsPinned for any child control?
Thank you.
Add a DependencyProperty ItemsSource to your window (of type IEnumerable<object> and in your window Template set the tabcontrol with ItemsSource="{TemplateBinding ItemsSource}". That will make the window have its own child collection, which will then be rendered as tab items in the tabcontrol.
I'm developing a custom control which has a button that opens a popup.
When that popup contains another instance of my custom control (which also has a button that opens another popup, e.g. a calendar) some problems occur.
The second (nested) popup won't act as suspected. Clicks don't work, won't close, when parent popup is closed.
Are there any specific best practices when using nested popups?
I had the same issue. We have a custom DropDownSubsetSelector control in our wpf controls library. This control has a Popup in its control template with StaysOpen="False". Today I had to put this control on a custom view that is located inside wpf's Popup control with StaysOpen="False" and was wondered of this unexpected nested Popups behaviour. My workaround for this issue was to inspect Microsoft's source code of a classical ComboBox control. You can find it here Combobox Source. As you can see its behaviour on a Popup control is exactly the same you expect from Popup being located on another Popup, and it's template has Popup inside (dropdown for selectable Items).
You must subscribe to events MouseDownEvent and LostMouseCaptureEvent and deal with mouse capturing for proper handling of MouseDownEvent outside of Popup control's area. Inspect and just copy some source code for your nested ExtendedPopup. You can inherit it from classical Popup.
I have implemented my MVVM error message as a message dialog that subscribes to error messages via a mediator class, so that other viewmodels can notify it if any errors occur.
When an error occurs, I set the visibility attribute in the viewmodel to Visible, to display the error window. This is all bound in the Error window from the viewmodel.
However, this window is NOT modal! I need to show it as a dialog and not just set the visibility to true - is there any kind of binding I can do, even if I have to extend the functionality of the window? I'd rather not break MVVM if I can avoid it.
Thanks!
The View/ViewModel split is meant to divide look from functionality. I firmly believe the Window is functionality and look rolled into one. For instance, what if in your ErrorMessageViewModel, you had this code that executes when there are errors:
class WindowViewModel : Window
{
}
.
.
.
WindowViewModel newDialog = new WindowViewModel();
newDialog.Content = myErrorListViewModel;
newDialog.Parent = mainWindowViewModel;
newDialog.ShowDialog();
So the contents of the dialog is the ViewModel for your error list. Define your View as a data template that automatically applies itself to the error list ViewModel.
Doesn't that look like MVVM?
The fact is, the Window class is a ViewModel for the Window you see on the screen. By changing the properties of the Window object, it affects the "view" just like if the properties of the WindowView were bound to a WindowViewModel. The only thing missing is the ability to "restyle" the Window using WPF, and it doesn't matter how hard you try to implement it, you're not going to be able to do that. The user can restyle a Window by modifying their desktop theme, but you're not in control of it. The best you can do is turn off the chrome and/or make it full screen.
You find an example how windows (don't matter if they are modal or not) are shown, in the ViewModel example of this project:
WPF Application Framework (WAF)
http://waf.codeplex.com
I am also working on a MVVM project where I need modal dialogboxes or messageboxes. I have found the following way of solving it:
The software uses only one window. The layout root element is a Grid with no row- or columndefinitions. The grid has three children:
A dockpanel that contains all the usual stuff like menus, tabbed views, status bar and so on.
A grid that has a gray background and a 50% opacity. This is used as a veil to cover the dockpanel when a modal box is in effect. The veil grid is usually collapsed.
A grid holding modal views, this is usually collapsed.
The viewmodel for the main window has a member called Modal. If this is null, the two grids for modal use are collapsed through databinding and a converter for Visibility.Collapsed.
When the program wants to display for example a modal message box, a MessageBoxViewModel is instantiated and assigned to MainViewModel.Modal. The MessageBoxViewModel has a Command for an OK-button. This Command raises an event that sets the MainViewModel.Modal to null again.
The veil grid occludes the main DockPanel, so that no controls outside the Modal control accept input.
Your program can either run a messagepump until OK is pressed, or the OK-Command can trigger the next. There are many ways of solving different needs, but the Model-ModelView solution should support them.
I feel that this is as good a model of the view in the modal mode as one can hope for.
I made a behhavior to tie some modal dialogs to the command.
http://www.clr-namespace.com/post/MVVMModal-dialog-before-running-Command.aspx
<Confirm:Confirm IsConfirm="{Binding ElementName=checkBoxConfirm, Path=IsChecked}"
Command="{Binding Path=ButtonCommand}"
CommandParameter="{Binding ElementName=textBoxParameter, Path=Text}"
ConfirmMessage="Are you sure you want to fire the command?"
ConfirmCaption="Question" >
</Confirm:Confirm>
In my recent blog post you can find simple solution for Modal Dialogs and Message Boxes in MVVM for Silverlight but this can be simply reused in WPF:
Modal dialogs with MVVM and Silverlight 4
i'm using the same method as Scott Whitlock.
there is just one more important property to set:
class ModalDialog: Window
{
}
.
.
.
var dlg = new ModalDialog {
Content = viewModelName,
**TopMost = true,**
Parent = mainWindowViewModel
};
dlg.ShowDialog();