Hide context menu in TaskBar Icon after click "Exit" - c#

When I click the exit button in context menu it still appears until the method finish.
<tb:TaskbarIcon Name="TrayIcon" IconSource="Icon.ico" ToolTipText="text" Visibility="Visible" MenuActivation="LeftOrRightClick">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu Name="ContextMenu">
<ContextMenu.Style>
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="ItemsPanel" Value="{StaticResource MenuTPL}"/>
</Style>
</ContextMenu.Style>
<MenuItem x:Name="LogIn" Click="LogIn_Click" Header="points"></MenuItem>
<MenuItem x:Name="Exit" Click="Exit_Click" Header="exit"></MenuItem>
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
And the c# code is:
private void Exit_Click(object sender, RoutedEventArgs e)
{
TrayIcon.Visibility = Visibility.Hidden;
TrayIcon.ContextMenu.Visibility = Visibility.Hidden;
Application.Current.Shutdown();
}
I can't put the shutdown to backgroud. Is there any way to solve it?

You have to leave the event handler. Use Dispatcher.BeginInvokefor it.
Dispatcher.BeginInvoke((Action)(()=> { Application.Current.Shutdown(); }));

Related

How do I make a textbox visible and hidden with a checkbox?

So I am trying to make my textbox invisible when a checkbox is not checked. Everything works fine untill I check the box and then uncheck it again. The textbox will stay visible.
private void chbon_Checked_1(object sender, RoutedEventArgs e)
{
if (cchbon.IsChecked == true)
{
txtshow.Visibility = System.Windows.Visibility.Visible;
}
if (chbon.IsChecked == false)
{
txtshow.Visibility = System.Windows.Visibility.Hidden;
}
}
This is the XAML for the Checkbox:
<CheckBox x:Name="chbon" Content="On" HorizontalAlignment="Left" Margin="175,84,0,0" VerticalAlignment="Top" Checked="chbon_Checked_1"/>
<TextBox x:Name="txtshow" HorizontalAlignment="Left" Height="23" Margin="272,82,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="29" Visibility="Hidden"/>
The event Checked does not fire when uncheck happens.
The event Unchecked is for that purpose.
... Checked="chbon_Checked" Unchecked="chbon_Unchecked"/>
and no need to monitor cchbon.IsChecked in code behind:
private void chbon_Checked(object sender, RoutedEventArgs e)
{
txtshow.Visibility = System.Windows.Visibility.Visible;
}
private void chbon_Unchecked(object sender, RoutedEventArgs e)
{
txtshow.Visibility = System.Windows.Visibility.Hidden;
}
Alternatively, you can do it via binding and a converter:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
...
<CheckBox x:Name="chbon"/>
<TextBox x:Name="txtshow" Visibility="{Binding ElementName=chbon, Path=IsChecked,
Converter={StaticResource BoolToVis}, FallbackValue=Hidden}"/>
Note that,
Once you managed this approach you may want to implement a custom converter since the built-in BooleanToVisibilityConverter returns Visible/Collapsed for True/False input (and not Visible/Hidden)
The Checked event handler will only hit when you check the checkbox, not uncheck it. You can also use the Unchecked handler in your XAML that would make the textbox hidden.
private void chbon_Unchecked(object sender, RoutedEventArgs e)
{
txtshow.Visibility = System.Windows.Visibility.Hidden;
}
private void chbon_Checked_1(object sender, RoutedEventArgs e)
{
txtshow.Visibility = System.Windows.Visibility.Visible;
}
when CheckBox goes to unchecked state, Unchecked event fires (simmetric to Checked). Add event handler to both of them.
<CheckBox x:Name="chbon"
Content="On"
HorizontalAlignment="Left"
Margin="175,84,0,0"
VerticalAlignment="Top"
Checked="chbon_Checked_1"
Unhecked="chbon_Checked_1"/>
private void chbon_Checked_1(object sender, RoutedEventArgs e)
{
txtshow.Visibility = cchbon.IsChecked ? Visibility.Visible : Visibility.Hidden;
}
It is common to use binding to boolean property to set Visibility of some element. There is a BooleanToVisibilityConverter in .NET, which returns Visible for true, and Collapsed for false. Collapsed is different from Hidden: Hidden element stil claims the space on the screen as if it was Visible.
There is a way to achieve everything in XAML using a Trigger:
<CheckBox x:Name="chbon" Content="On"
HorizontalAlignment="Left" Margin="175,84,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="txtshow"
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="23" Width="29" Margin="272,82,0,0" TextWrapping="Wrap">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=chbon}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
<TextBox/>

Can't access the events inside the GridViewColumn's Content

When I add an event to the ListViewItem,
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="PreviewMouseDown" Handler="listViewItem_MouseDown" />
</Style>
Then add another event in the content inside the GridViewColumn,
<GridViewColumn Header="Action">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image x:Name="imgEdit"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Width="40"
Height="40"
Tag="{Binding ProductBarcode}"
Cursor="Hand"
MouseDown="img_MouseDown">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/Resources/edit_button.png" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="/Resources/edit_button_hovered.png" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
I can't fire the event in the Image control. The one that is firing is the event in the ListViewItem. How to access the event in the Image control?
Here are the events:
private void img_MouseDown(object sender, MouseButtonEventArgs e)
{
switch ((sender as Image).Name)
{
case "imgEdit":
MessageBox.Show("EDIT");
break;
default:
break;
}
}
private void listViewItem_MouseDown(object sender, RoutedEventArgs e)
{
MessageBox.Show("ROW CLICKED");
}
The PreviewMouseDown event of the ListViewItem will always be raised before the MouseDown event of the Image. This is how routed events work: https://msdn.microsoft.com/en-us/library/ms742806(v=vs.110).aspx. PreviewMouseDown is a tunneling event and MouseDown is a bubbling event.
If you don't want to handle the PreviewMouseDown event when the Image is clicked you could check the type of the OriginalSource of the RoutedEventArgs and return immediately from the event handler if it is Image:
private void listViewItem_MouseDown(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is Image)
return; // do nothing
MessageBox.Show("ROW CLICKED");
}
Try:
private void listViewItem_MouseDown(object sender, MouseButtonEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
MessageBox.Show("ROW CLICKED");
}));
}

Open Buttons ContextMenu on Left Click

I have a button with a context menu, my requirements are to show the context menu on left click
The problem is that the <ContextMenu ItemsSource="{Binding LineItems}" isn't being updated/refresh when the context menu opens. However If i right click first, items are loaded fine
XAML
<Button x:Name="BtnMessageChannel" Click="BtnMessageChannel_Click" Grid.Row="0" Grid.Column="2" Height="23" Width="23" ToolTip="Message Channel" >
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding LineItems}" x:Name="CtxMessageChannel">
<ContextMenu.Resources>
<Image x:Key="img" Source="{Binding Icon}" x:Shared="false"/>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding DisplayName}"/>
<Setter Property="Icon" Value="{StaticResource img}">
</Setter>
</Style>
</ContextMenu.Resources>
</ContextMenu>
</Button.ContextMenu>
<Image Source="Images/mail_send.png" HorizontalAlignment="Left" Width="16" />
</Button>
Code Behind
private void BtnMessageChannel_Click(object sender, RoutedEventArgs e)
{
BtnMessageChannel.ContextMenu.GetBindingExpression(ContextMenu.ItemsSourceProperty)
.UpdateTarget();
BtnMessageChannel.ContextMenu.Visibility = Visibility.Visible;
BtnMessageChannel.ContextMenu.IsOpen = true;
}
Is there any easy solutions to this problem?
An easy solution is to update your button event handler to simulate a right click if the context menu is not currently open.
private void BtnMessageChannel_Click(object sender, RoutedEventArgs e)
{
if (!BtnMessageChannel.ContextMenu.IsOpen)
{
e.Handled = true;
var mouseRightClickEvent = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Right)
{
RoutedEvent = Mouse.MouseUpEvent,
Source = sender,
};
InputManager.Current.ProcessInput(mouseRightClickEvent);
}
}

Dynamically add radiobuttons in submenu in C# WPF

I would like to implement a dynamical menu in my application, written in C# and using WPF.
MenuSubSerialPortSelect.Items.Clear();
foreach (string element in GlobalVars.ActualSerialPorts)
{
MenuItem item = new MenuItem();
item.Header = element;
MenuSubSerialPortSelect.Items.Add(item);
}
The sub-menu adding is functional, but how can I add some radio buttons in this style?
I've read some websites that described that there must be used another "template", but I can't find a matched solution for me.
The attribute item.IsCheckable = true; is not a solution for me -- the entries must be blocked against each other.
It would be great if somebody could give me a tip on how to do that.
Try this
<Window x:Class="Stackoverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Stackoverflow"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<RadioButton x:Key="RadioButton" HorizontalAlignment="Center"
GroupName="MyGroup" IsHitTestVisible="False"/>
<Style TargetType="MenuItem">
<Setter Property="Icon" Value="{StaticResource RadioButton}"/>
<EventSetter Event="Click" Handler="MenuItem_Click" />
</Style>
</Window.Resources>
<Grid Background="Red">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Print"/>
<MenuItem Header="Save"/>
<MenuItem Header="Open"/>
<MenuItem Header="Delete"/>
<MenuItem Header="Update"/>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
private void MenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
{
MenuItem menuItem = sender as MenuItem;
if (menuItem != null)
{
RadioButton rb = menuItem.Icon as RadioButton;
if (rb != null)
{
rb.IsChecked = true;
}
}
}
}
Here i just have static menuitems.

Get Text of a ContextMenu.ItemsSource generated MenuItem in WPF

I´ve got a Click-method of a MenuItem in a ContextMenu. In this method, I need the text of the item I´ve clicked.
Here´s the code:
private void menuItemKostenstellen_Click(object sender, RoutedEventArgs e) { }
I already tried with e.Source but that didn´t work.
How can I get this?
Use following:
<ContextMenu Name="conKostenstelle" >
<MenuItem Header="Kostenstellen" Name="menuItemKostenstellen">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<EventSetter Event="Click" Handler="MenuItem_Click" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
LinkedList<String> kliste = kosrep.GetKostenstellen();
menuItemKostenstellenunter.ItemsSource = kliste;
try this
private void menuItemKostenstellen_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
string title = mi.Header.ToString();
}
Use ItemContainerStyle Property for Click Event on all MenuItems
<ContextMenu>
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<EventSetter Event="Click" Handler="MenuItem_Click" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>

Categories