Mahapps.Metro Dialog not showing in Command.Execute - mahapps.metro

I want to show a "loading" dialog while doing some work. When I trigger the job with a button click event, it is working (the main window is grayed out and the dialog is shown modal).
XAML:
<Button Click="ClickButton" ... />
The View:
private void ClickButton(object sender, RoutedEventArgs e)
{
var dialog = this.Resources["MyDialog"];
this.ShowMetroDialogAsync(dialog as BaseMetroDialog);
... do the work
}
But when I use a command
<Button Command="{Binding MyCommand}"
and call the dialog in the commands Execute method
public async void Execute(object parameter)
{
MainWindow metroWindow = Application.Current.MainWindow as MainWindow;
var dialog = metroWindow.Resources["MyDialog"];
await this.ShowMetroDialogAsync(dialog as BaseMetroDialog);
... do the work
}
the main window is only grayed out and no dialog is shown.

Related

How can I change a label content to something else using a method

This is my method I created to edit the content of the label inside TourCollection.cs:
public void Start()
{
MainWindow mw = new MainWindow();
mw.Label1.Content= "Hello";
}
This is the button event i created to run the method OnClick in MainWindow.cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
TourCollection t = new TourCollection();
t.Start();
}
This is the button code inside MainWindow.xaml:
<Button Content="Find Out More" Canvas.Left="100" Canvas.Top="258" Width="100" RenderTransformOrigin="-0.326,-0.981" Click="Button_Click"/>
This is my label I created in MainWindow.xaml:
<Label x:Name="Label1" Content="Label" Canvas.Left="254" Canvas.Top="33"/>
I see what you want to do
Make the label Modifies public in the design properties.
In your Button_Click do this
t.Start(this);
And your Start function will now become
public void Start(MainWindow instance)
{
instance.Label1.Content= "Hello";
}
Your problem was you were creating a new Main window and changing the text there. What you wanted was to change the text in Label1 of the currently open window.

WPF weird window switching on double-click

Does anybody know how to implement a double-click event handler that opens a new window in a way the new window becomes the front most window? (Just the behavior that is normally expected).
In WPF there is a strange behavior of windows when opening a second window in the double-click event handler. The second window opens but the first window, where the double-click-event was fired, becomes activated again immediately.
Opening a window in a click event handler, works as expected. The second window opens and remains the front window.
For demonstration purposes I created the following application. Two window classes with just a button control. To distinguish between click and double-click on the button control, the click-event works only if the left shift key is pressed.
After double-click
http://blog.mutter.ch/wp-content/uploads/2014/05/wpf_window1.png
After click (this is also the expected behavior for double-click)
http://blog.mutter.ch/wp-content/uploads/2014/05/wpf_window2.png
Main Window
<Window x:Class="WpfWindowSwitching.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="600">
<Grid>
<Button Margin="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MouseDoubleClick="doubleClick"
Click="click">
<TextBlock FontWeight="Bold"
FontSize="22">
I am the first Window, double click this button...
</TextBlock>
</Button>
</Grid>
</Window>
The code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void doubleClick(object sender, MouseButtonEventArgs e)
{
openNewWindow();
}
private static void openNewWindow()
{
var window = new SecondWindow();
window.Show();
}
private void click(object sender, RoutedEventArgs e)
{
if (!Keyboard.IsKeyDown(Key.LeftShift)) return;
openNewWindow();
}
}
Second Window
<Window x:Class="WpfWindowSwitching.SecondWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SecondWindow" Height="200" Width="600">
<Grid>
<Button Margin="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="click">
<TextBlock FontWeight="Bold"
FontSize="22">
I am the second Window
</TextBlock>
</Button>
</Grid>
</Window>
The code behind:
public partial class SecondWindow : Window
{
public SecondWindow()
{
InitializeComponent();
}
private void click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
After MouseDoubleClick event, MouseUp event is raised which gets handled on MainWindow. Hence secondary window gets activated momentarily and with subsequent event bubbling, main window gets activated.
In case you don't want that, you can explicitly stop event bubbling by setting e.Handled to True after mouse double click event. This way secondary window will remain activated.
private void doubleClick(object sender, MouseButtonEventArgs e)
{
openNewWindow();
e.Handled = true;
}

How to wait for click then close the Splashscreen in WPF application?

I have a WPF Application and there's a button which shows an image (Splash Screen) containing the company logo and the name of the developers of the application. I want this image be shown until the user interacts with whatever. When user clicks or enters a keyboard key, the image must close. Refer to the comment line in my code.
private void Info_BeforeCommandExecute(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
{
SplashScreen SS = new SplashScreen("Images/InfotecSplashScreenInfo.png");
SS.Show(false);
// Need to do something here to wait user to click or press any key
SS.Close(TimeSpan.FromSeconds(1));
}
You could add a handler for the Keyboard class using AddKeyDownHandler:
private void Info_BeforeCommandExecute(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
{
SplashScreen SS = new SplashScreen("Images/InfotecSplashScreenInfo.png");
SS.Show(false);
KeyEventHandler handler;
handler = (o,e) =>
{
Keyboard.RemoveKeyDownHandler(this, handler);
SS.Close(TimeSpan.FromSeconds(1));
};
Keyboard.AddKeyDownHandler(this, handler);
}
This would allow you to close the splash screen after the user presses a key.
Reed's answer is no doubt easiest, but you could also avoid using SplashScreen altogether and just use a custom Window to give you full control.
YourCode.cs
private void Info_BeforeCommandExecute(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
{
SplashWindow SS = new SplashWindow();
SS.ShowDialog(); // ShowDialog will wait for window to close before continuing
}
SplashWindow.xaml
<Window x:Class="WpfApplication14.SplashWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SplashWindow" Height="350" Width="525">
<Grid>
<!-- Your Image here, I would make a Custom Window Style with no border and transparency etc. -->
<Button Content="Click Me" Click="Button_Click"/>
</Grid>
</Window>
SplashWindow.xaml.cs
public partial class SplashWindow : Window
{
public SplashWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Once user clicks now we can close the window
// and/or add keyboard handler
this.Close();
}
}

RelayCommand for a button in other window

I have a mainwindow, and another window called Loginwindow.
In some point this LoginWindow will shows up to get some login info...
In the LoginWindow I have a button and it's Command property is binding to OkCommand in the MainViewModel like this:
<Button Content = "Ok" Command="{Binding OkCommand}"/>
In my MainVeiwModel I added a OkCommand RelayCommand
public RelayCommand OkCommand
{
get { return new RelayCommand(OkClose); }
}
private void OkClose()
{
MessageBox.Show("Close Login");
}
this code executes well and the MessageBox has appeared when I click the Ok button..
but how do I close the LoginWindow when I click the Ok button...
I propose very simple solution. Don't bind command and simply handle Clicked event in the LoginWindow codebehind. It will be really easy to close the Window from there.
Is there another reason, why you handle OK button in VM of different window?
In XAML (window.xaml):
<Button Content="OK" Click="button1_Click" />
In code behind (window.xaml.cs):
private void button1_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
EDIT:
First way, MVVM style
Add event RequestClose to your VM. And raise this event when OkCommand executed.
Where you show your dialog and bind VM to window, also add handler to that event like:
var window = new MyDialogWindow();
window.DataContext = loginViewModel;
loginViewModel.RequestClose += (s, e) =>window.Close();
Second way, pass window as CommandParameter:
Set Name property for your window:
<Button Content = "Ok" Command="{Binding OkCommand}"
CommandParameter="{Binding ElementName=_windowName}"/>
Or
<Button Content = "Ok" Command="{Binding OkCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
And close window in command execute:
public void Execute(object parameter)
{
var wnd = parameter as Window;
if (wnd!= null)
wnd.Close();
}
See also:
Property IsDefault and IsCancel for Button.

WPF ListBox drag & drop interferes with ContextMenu?

I'm implementing drag & drop from a ListBox, but I'm seeing some strange behaviour with a ContextMenu elsewhere in the window. If you open the context menu and then start a drag from the ListBox, the context menu closes but won't open again until after you perform another drag.
Does this make sense? Anybody got any ideas what might be going on?
<ListBox Grid.Row="0" ItemsSource="{Binding SourceItems}" MultiSelectListboxDragDrop:ListBoxExtension.SelectedItemsSource="{Binding SelectedItems}" SelectionMode="Multiple" PreviewMouseLeftButtonDown="HandleLeftButtonDown" PreviewMouseLeftButtonUp="HandleLeftButtonUp" PreviewMouseMove="HandleMouseMove"/>
<ListBox Grid.Row="1" ItemsSource="{Binding DestinationItems}" AllowDrop="True" Drop="DropOnToDestination" />
<Button Grid.Row="2">
<Button.ContextMenu>
<ContextMenu x:Name="theContextMenu">
<MenuItem Header="context 1"/>
<MenuItem Header="context 2"/>
<MenuItem Header="context 3"/>
</ContextMenu>
</Button.ContextMenu>
Button with context menu
</Button>
...
public partial class Window1
{
private bool clickedOnSourceItem;
public Window1()
{
InitializeComponent();
DataContext = new WindowViewModel();
}
private void DropOnToDestination(object sender, DragEventArgs e)
{
var viewModel = (WindowViewModel)e.Data.GetData(typeof(WindowViewModel));
viewModel.CopySelectedItems();
}
private void HandleLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var sourceElement = (FrameworkElement)sender;
var hitItem = sourceElement.InputHitTest(e.GetPosition(sourceElement)) as FrameworkElement;
if(hitItem != null)
{
clickedOnSourceItem = true;
}
}
private void HandleLeftButtonUp(object sender, MouseButtonEventArgs e)
{
clickedOnSourceItem = false;
}
private void HandleMouseMove(object sender, MouseEventArgs e)
{
if(clickedOnSourceItem)
{
var sourceItems = (FrameworkElement)sender;
var viewModel = (WindowViewModel)DataContext;
DragDrop.DoDragDrop(sourceItems, viewModel, DragDropEffects.Move);
clickedOnSourceItem = false;
}
}
}
It seemed to be something to do with the mouse capture!?
The normal sequence of events during a drag goes something like this...
The PreviewMouseLeftButtonDown
handler gets called and
ListBox.IsMouseCaptureWithin is
false.
The PreviewMouseMove handler
gets called. By this time
ListBox.IsMouseCaptureWithin is true.
During the PreviewMouseMove handler
DragDrop.DoDragDrop gets called and
sometime during this the mouse
capture is released from the ListBox.
But, what seems to happening for a drag started when the context menu is open is...
The PreviewMouseLeftButtonDown
handler gets called and
ListBox.IsMouseCaptureWithin is
false.
The PreviewMouseMove handler gets
called. But this time
ListBox.IsMouseCaptureWithin is
still false.
Sometime after the end of the
PreviewMouseMove handler the
ListBox then gets the mouse capture
(ListBox.IsMouseCaptureWithin
becomes true)
The result of this is that after the drag, the ListBox still has the mouse capture so any clicks on the button to open the context menu are actually going to the listbox not the button.
Adding the following code to the start of the PreviewMouseLeftButtonDown handler seems to help by swallowing up the click that closes that context menu rather than trying to start a drag from it...
if (!contextMenuCloseComplete)
{
sourceElement.CaptureMouse();
return;
}
...with the contextMenuCloseComplete bool getting set in handlers for the context menu's Closed and Opened events.
Does that make sense? Does anyone understand where this mouse capture behaviour is coming from?

Resources