Caliburn Micro run code on label click - c#

I'm using WPF alongside Caliburn.Micro. I want any code to be run when a label is clicked. I tried some googling and found out about cal:Message.Attach.
XAML:
<Label x:Name="Info" Content="Info" HorizontalAlignment="Left" Margin="305,440,0,0"
VerticalAlignment="Top" FontFamily="Tahoma" FontSize="10" FontWeight="Bold" cal:Message.Attach="[Action ShowAboutWindow()]"/>
C#:
public void ShowAboutWindow()
{
MessageBox.Show("xyz"); // just to test whether ShowAboutWindow is executed whatsoever (see explanation below)
WindowManager.ShowWindow(new AboutViewModel(EventAggregator, WindowManager, SettingsManager));
}
However, ShowAboutWindow isn't run whatsoever. I added a MessageBox to make sure that it isn't the WindowManager screwing it up.
How can I achieve what I desire?
EDIT 1: What I had tried even before was adding a public void Info() method to the ViewModel, as this works for buttons. But it didn't in this case.

Try attaching to the MouseLeftButtonUp event to simulate a click event after the mouse left button is released.
cal:Message.Attach="[Event MouseLeftButtonUp] = [Action ShowAboutWindow()]"

Related

WPF Why button's background is blinking after press?

I created a UserControl, and added a Button inside it removing the Background and Text properties:
<Button x:Name="Button"
HorizontalAlignment="Center"
Height="40"
VerticalAlignment="Center"
Width="40"
RenderTransformOrigin="0,-2"
Margin="0,0,0,0"
BorderBrush="{x:Null}"
Click="Button_Click"
Background="{x:Null}"/>
I also hadled the Button Click event as below:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button.Content = new cross();
}
The above code fills the Button content with another UserControl which is a simple cross pic.
I have placed the UserControl with the Button into a MainWindow app and after pressing Button, it starts blinking - background is fluently changing between two colours. Beside my functionality from code works good. I just don't know how to get rid of that blinking background.
Before click:
After click:
You could set Focusable="False" at your Button to achive this.
But you should read about the Focusableproperty in the MSDN to check if it's ok for you. I guess you can't focus the Buttonusing the tab key anymore. But maybe that's not a problem for you.

MouseUp event doesnt work on left click

I am making a GUI using Windows Presentation Foundation (WPF). When I mouse click a button (left or right), I want a message box shown. So far I have managed to make an example from tutorials, but it only works when I right-click, and not when I left-click the button. I cannot see anything in my code, which should prevent left-click from working, so I hope you can help me.
XAML code
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="72">
Hello, WPF!
</TextBlock>
<!-- This button shuld activate the even MyButton_MouseUp -->
<Button Margin="200,250,200,20" Name="MyButton" MouseUp="MyButton_MouseUp">
Test
</Button>
</Grid>
C# code
// This only works on right-click
private void MyButton_MouseUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Hello world!");
}
You can subscribe to the PreviewMouseUp's Tunneled event instead of MouseUp:
<Button Margin="200,250,200,20" Name="MyButton" PreviewMouseUp="MyButton_MouseUp" />
The PreviewMouseUp's Routing strategy is Tunneling, i.e it will go down of the VisualTree hierarchy, and so the Tunnel events are triggered before the Bubble events.
In addition to S. Akbari's post, this one is worth reading in order to understand why right-click works, and left-click does not...
How to use mouseDown and mouseUp on <button/>

WPF Buttons not instantiating

I'm having the weirdest problem and it's driving me insane.
I've created a WPF MVVM program and everything was working alright, however, now when I open the program and click on a button, I receive a System.NullReferenceException. I put a breakpoint where the error occurs and the button isn't instantiated, however, the form shows just fine and the buttons are clickable. In fact, none of the buttons instantiate (every button on my form gives the same error, and when I set a breakpoint after InitializeComponent(), none of the buttons show up under this - all the other components show up.
Here is sample code for the button:
MainWindow.xaml
<Button Content="A"
Command="{Binding KeyButtonClickCommand}"
Style="{StaticResource keyButtonStyle}" />
The method throwing an error is in my ViewModel, the button is bound to a command:
private void keyButton_Click(object sender)
{
Button btn = (Button)sender;
string tempKey = "";
tempKey = btn.Content.ToString();
this.Key = tempKey;
}
Breakpoint after InitializeComponent()
Breakpoint after error
Like I said, was working just fine earlier, now just went on the fritz.
What worries me most is that maybe I've done something that I shouldn't have and it might affect future projects. I'd just like to double-check whether it's that, or just a freak occurrence.
Thanks.
If I am understanding your question correctly you are getting the argument for your keyButton_Click method as null.
This is most likely because you are not passing in a CommandParameter to your command. If you want to pass the button itself into the command, try the following XAML.
<Button Content="A"
Command="{Binding KeyButtonClickCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Style="{StaticResource keyButtonStyle}" />
I do want to note the whole point of MVVM is to not interact with the actual UI layer directly in your ViewModel and when you pass your button to your ViewModel like this you are doing exactly that.
Edit : As noted in the comments if you want to pass "A" as argument to your command you should just set that as your CommandParameter.
<Button Content="A"
Command="{Binding KeyButtonClickCommand}"
CommandParameter="A"
Style="{StaticResource keyButtonStyle}" />

Is this concept of a button containing a textbox possible?

Recently I had been looking for a way to make the tabs in a TabControl editable and came across This example on telerik's website. That did exactly what I wanted but it got me thinking about a similar usage for buttons. I was wondering if it would be possible to use something like that and make a button that would show a textbox instead of the content presenter when say, you right click the button? I tried to make something like this work but so far have only ended up with a blank button.
<Button x:Name="SB" Height="222" Width="222" Click="SB_Click">
<ContentControl.ContentTemplate>
<DataTemplate>
<local:SuperButton Content="{Binding Path=x, Mode=TwoWay}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</Button>
Where x is a string variable and using the code behind from the link above (with a class name change, of course).
edit: This button will be in an itemscontrol, so I don't think naming the inner elements in xaml will work, but I do like the ease of Wolfgang's answer.
The WPF Content Model is really flexible and allows literally anything inside anything.
This is perfectly valid XAML:
<Button>
<TextBox/>
</Button>
Or even:
<Button>
<MediaElement Source="C:\Videos\WildLife.wmv"/>
</Button>
You can simply host a (e.g.) label (TextBlock) with the text AND a TextBox inside the Button and set their Visiblity properties.
That way, if you right click the button, the TextBox shows up.
<Button>
<Grid>
<TextBox Text=normal button caption" x:Name="label" />
<TextBox
x:Name="textbox"
Text="visible on right click"
MouseRightButtonDown="HandleRightClick"/>
</Grid>
</Button>
And then in your C# code create an event handler to set the Visiblity correctly.
void HandleRightClick(object sender, MouseButtonEventArgs e)
{
label.Visibility = Visibility.Collapsed;
textBlock.Visibility = Visibility.Visible;
}

StackOverflowException when trying to show a ContextMenu and clicking on its parent

I've encountered a weird behavior in WPF. Even though there are quite a few ways to avoid this problem, I'm trying to better understand why it's happening:
I created a new WPF application, just added a button which has a ContextMenu:
<Grid>
<Button x:Name="btnTest" Margin="10,10,10,10"
MouseEnter="BtnTest_OnMouseEnter" MouseLeave="BtnTest_OnMouseLeave">
<Button.ContextMenu>
<ContextMenu x:Name="myContext">
<TextBlock Text="Context Menu Text"></TextBlock>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
In the code behind I use MouseEnter to show the ContextMenu and MouseLeave to hide it:
private void BtnTest_OnMouseEnter(object sender, MouseEventArgs e)
{
myContext.PlacementTarget = btnTest;
myContext.Placement = PlacementMode.Bottom;
myContext.IsOpen = true;
}
private void BtnTest_OnMouseLeave(object sender, MouseEventArgs e)
{
myContext.IsOpen = false;
}
So now - I see the ContextMenu under the button when the mouse is on the button and it hides when the mouse leaves the button.
BUT when I click the button I get an exception
An unhandled exception of type 'System.StackOverflowException'
occurred in WindowsBase.dll
Question is - Why is the Mouse Click, specifically, triggering this exception? I don't have any code of mine running on the Click event, yet without clicking an exception doesn't occur...
BTW: Same will happen if I replace the Button with an Image for instance, so it doesn't seem to be caused by a specific control...
Change your XAML like this:
<Grid>
<Popup x:Name="myContext">
<TextBlock Text="Context Menu Text"></TextBlock>
</Popup>
<Button x:Name="btnTest" Margin="10,10,10,10"
MouseEnter="BtnTest_OnMouseEnter" MouseLeave="BtnTest_OnMouseLeave">
</Button>
</Grid>
I think there is a loop of this sort going on in your code:
you enter the button, the popup shows
you click, popup hides (default behavior of contextmenu)
button gets focus, popup is shown again
What happens if you set the ´StaysOpen´ property of the ContextMenu? If you then dont get this behavior anymore my suspicion is correct.

Categories