WPF listboxitem contextmenu - wpf

I'm trying to create a ContextMenu for a ListBox. It just should be displayed when a ListBoxItem is selected by a right mouse button click. But the ContextMenu opens whenever a right click is done in that ListBox, even when it's empty.
This is my code:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<Grid>
<ListBox Name="listIn"
Width="148"
Height="175"
Margin="25,52,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ItemsSource="{Binding Path=groupid}"
SelectionChanged="listBox1_SelectionChanged"
SelectionMode="Extended" />
<ListBox Name="listOut"
Width="148"
Height="175"
Margin="335,52,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
MouseRightButtonDown="ListBoxItem_MouseRightButtonDown"
SelectedItem="listBox2_SelectionChanged"
SelectionChanged="listBox2_SelectionChanged"
SelectionMode="Extended">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="update" />
<MenuItem Header="delete" />
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
<Button Name="cmdRein"
Width="75"
Height="23"
Margin="215,75,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="button1_Click"
Content="moveRight" />
<Button Name="cmdRaus"
Width="75"
Height="23"
Margin="217,0,0,145"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Click="button2_Click"
Content="moveLeft" />
<Button Name="button1"
Width="59"
Height="23"
Margin="0,14,330,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="button1_Click_1"
Content="Load" />
<TextBox Name="textBox1"
Width="83"
Height="23"
Margin="25,15,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
TextChanged="textBox1_TextChanged" />
</Grid>

<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Item 1"/>
<MenuItem Header="Item 2"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here your Adding ContextMenu for ListBox. This ContextMenu will opens when you right click on the Listbox itself.. If you need the ContextMenu for ListBoxItem alone, initialize ContextMenu for ListBoxItem.

You can define an ItemTemplate for the ListBox like:
<ListBox ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Item 1"/>
<MenuItem Header="Item 2"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The ItemsSource Item is an ObservableCollection<string>

Related

Remove MenuItem White Space Inside ComboBox

I have a menuitem nestled within a combobox and I've not been able to get rid of the terrible white space to the left and right of it.
The code is:
<Grid>
<ComboBox Name="SettingsCmbx" Text="Options" Foreground="White" VerticalContentAlignment="Center" HorizontalContentAlignment="Stretch" Width="80" Style="{StaticResource blackGradientComboBox}" Margin="3">
<ComboBox.ItemsSource>
<CompositeCollection>
<!--<ComboBoxItem Name="Options" IsEnabled="False" Style="{StaticResource blackComboBoxItem}">Options</ComboBoxItem>-->
<ComboBoxItem Style="{StaticResource blackComboBoxItem}">Guidelines</ComboBoxItem>
<ComboBoxItem Style="{StaticResource blackComboBoxItem}">Copy Investigation</ComboBoxItem>
<MenuItem Name="CurrencySelectMenuItem" Header="Currency" Background="Black" Foreground="White" BorderThickness="0" Margin="0" BorderBrush="Black" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<MenuItem Name="DollarSelectMenuItem" Tag="36" Header="$ - Dollar" Background="Black" Foreground="White"></MenuItem>
<MenuItem Name="PoundSelectMenuItem" Tag="163" Header="£ - Pound" Background="Black" Foreground="White"></MenuItem>
</MenuItem>
<ComboBoxItem Style="{StaticResource blackComboBoxItem}">About</ComboBoxItem>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
<TextBlock Name="OptionsTxtBlk" Text="Options" IsHitTestVisible="False" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
It looks like this:
I resolved this by adding negative margins on either side. Margin = "-5,0,-5,0"

MenuItem Highlight Stays After MouseLeave

I have this menuitem inside of a combobox:
<MenuItem Name="CurrencySelectMenuItem" Header="Currency" Width="Auto"
Background="Black" Foreground="White" BorderThickness="0" Margin="0"
BorderBrush="Black" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
When I highlight the item, it does what I want: it pops up the way it should to display it's children, and highlights to show that it's focused. However, when the mouse leaves, the menuitem stays highlighted, even after clicking some other part of my application.
I tried setting the IsFocused property but it is read only.
Can someone point me in the right direction please?
EDIT (code added):
<Grid>
<ComboBox Name="SettingsCmbx" Text="Options" Foreground="White" VerticalContentAlignment="Center" HorizontalContentAlignment="Stretch" Width="80" Style="{StaticResource blackGradientComboBox}" Margin="3">
<ComboBox.ItemsSource>
<CompositeCollection>
<!--<ComboBoxItem Name="Options" IsEnabled="False" Style="{StaticResource blackComboBoxItem}">Options</ComboBoxItem>-->
<ComboBoxItem Style="{StaticResource blackComboBoxItem}">Guidelines</ComboBoxItem>
<ComboBoxItem Style="{StaticResource blackComboBoxItem}">Copy Investigation</ComboBoxItem>
<MenuItem Name="CurrencySelectMenuItem" Header="Currency" Background="Black" Foreground="White" BorderThickness="0" Margin="0" BorderBrush="Black" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<MenuItem Name="DollarSelectMenuItem" Header="_$ - Dollar" Background="Black" Foreground="White"></MenuItem>
<MenuItem Name="PoundSelectMenuItem" Header="_£ - Pound" Background="Black" Foreground="White"></MenuItem>
</MenuItem>
<ComboBoxItem Style="{StaticResource blackComboBoxItem}">About</ComboBoxItem>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
<TextBlock Name="OptionsTxtBlk" Text="Options" IsHitTestVisible="False" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
Here's the image:

How to remove or add an item from a WrapPanel?

I am trying to create a prototype where the user can show or display items by selecting the menu items. I need the item to be removed/Collapsed because I need the empty space to be taken by other items in WrapPanel. The content in the wrapPanel is generated dynamically with XMLDataProvider. I tried to assign commands for the menu items but was not able to make it work.
XAML:
<Grid Margin="20">
<Menu x:Name="Manage_Menu" HorizontalAlignment="Left" Background="{x:Null}" ScrollViewer.VerticalScrollBarVisibility="Auto" Foreground="#FF2A2A2A" Margin="0,0,0,5" >
<MenuItem Header="Show/Hide">
<MenuItem Header="1" Command="{x:Static local:MainWindow.FirstThumbVisibilityWindowCommand}" IsCheckable="true" IsChecked="True"/>
<MenuItem Header="2" Command="{x:Static local:MainWindow.FirstThumbVisibilityWindowCommand}" IsCheckable="true" />
<MenuItem Header="3" Command="{x:Static local:MainWindow.FirstThumbVisibilityWindowCommand}" IsCheckable="true" />
<MenuItem Header="4" Command="{x:Static local:MainWindow.FirstThumbVisibilityWindowCommand}" IsCheckable="true" />
<MenuItem Header="5" Command="{x:Static local:MainWindow.FirstThumbVisibilityWindowCommand}" IsCheckable="true" />
</MenuItem>
</Menu>
<Frame Content="Frame" Source="../tiles.xaml" NavigationUIVisibility="Hidden" />
</Grid>
I hope someone will be able to help.
The whole solution is available from here:
http://cid-0c29483cf3a6a14d.office.live.com/self.aspx/WPF%5E_Tests/DragDropWrapPanel%5E_3.rar
Please take a look. You will find Menu on top left corner that should be used to hide/show items inside the wrapPanel.
Thank you in advance.
One way to add or remove items from a wrap panel is use a ListBox with the ItemsPanel configured as a WrapPanel
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
Bind the ListBox to an ObservableCollection and then add and remove your view models from the bound collection.
Here is an example of changing the visibility of WrapPanel items from code.
Some sample XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Content="0" Click="Button_Click"/>
<Button Content="1" Click="Button_Click"/>
<Button Content="2" Click="Button_Click"/>
</StackPanel>
<WrapPanel Grid.Row="1" x:Name="wrapPanel">
<Rectangle Fill="Red" Width="100" Height="100"/>
<Rectangle Fill="Green" Width="100" Height="100"/>
<Rectangle Fill="Blue" Width="100" Height="100"/>
</WrapPanel>
</Grid>
and the button event handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
int index = int.Parse((string)((sender as Button).Content));
var child = this.wrapPanel.Children[index];
child.Visibility = child.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
which just toggles the visibility of the child corresponding to the text on the button.
Here is a quick-n-dirty version that is XAML only. It uses the built-in BooleanToVisibilityConverter, and Element binding.
<Window x:Class="WrapPanelHideItems.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WrapPanelHideItems" Height="300" Width="300">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="boolToVis" />
</Window.Resources>
<StackPanel>
<Menu>
<MenuItem Header="Show/Hide">
<MenuItem x:Name="mnuItemOne"
IsCheckable="True"
IsChecked="True"
Header="Show Item One" />
<MenuItem x:Name="mnuItemTwo"
IsCheckable="True"
IsChecked="True"
Header="Show Item Two" />
<MenuItem x:Name="mnuItemThree"
IsCheckable="True"
IsChecked="True"
Header="Show Item Three" />
<MenuItem x:Name="mnuItemFour"
IsCheckable="True"
IsChecked="True"
Header="Show Item Four" />
<MenuItem x:Name="mnuItemFive"
IsCheckable="True"
IsChecked="True"
Header="Show Item Five" />
</MenuItem>
</Menu>
<WrapPanel Orientation="Horizontal"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Gray">
<TextBlock Text="Item One"
Margin="5"
FontSize="25"
Foreground="Red"
Visibility="{Binding ElementName=mnuItemOne, Path=IsChecked,
Converter={StaticResource boolToVis}}"/>
<TextBlock Text="Item Two"
Margin="5"
FontSize="25"
Foreground="Blue"
Visibility="{Binding ElementName=mnuItemTwo, Path=IsChecked,
Converter={StaticResource boolToVis}}"/>
<TextBlock Text="Item Three"
Margin="5"
FontSize="25"
Foreground="Green"
Visibility="{Binding ElementName=mnuItemThree, Path=IsChecked,
Converter={StaticResource boolToVis}}"/>
<TextBlock Text="Item Four"
Margin="5"
FontSize="25"
Foreground="Yellow"
Visibility="{Binding ElementName=mnuItemFour, Path=IsChecked,
Converter={StaticResource boolToVis}}"/>
<TextBlock Text="Item Five"
Margin="5"
FontSize="25"
Foreground="Violet"
Visibility="{Binding ElementName=mnuItemFive, Path=IsChecked,
Converter={StaticResource boolToVis}}"/>
</WrapPanel>
</StackPanel>
</Window>
Of course, in a real-world app, you'd want to use things like Styles and perhaps DataBinding, but this shows that you don't have to be complex to get the results you want. Simpler is usually better.

Can't get focus on a TextBox inside a ListBox using Silverlight

I'm having a little trouble in silverlight with a databound ListBox containing databound TextBox elements. The items display correctly in the list and the TextBox is populated correctly but I can't get focus on the TextBox in the list. If I hover over the edges of the TextBox it highlights but it won't let me click into it to edit the text. Any ideas?
My XAML looks like this:
<ListBox x:Name="listImages">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="LayoutRoot" Background="White">
<Image Height="102" HorizontalAlignment="Left" Name="imgThumb" Stretch="UniformToFill" VerticalAlignment="Top" Width="155" Source="{Binding ImageFilename, Converter={StaticResource ImageConverter}}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="154,25,0,0" Name="txtAltText" VerticalAlignment="Top" Width="239" Text="{Binding Alt}" />
<dataInput:Label Height="19" HorizontalAlignment="Left" Margin="154,6,0,0" Name="lblAltText" VerticalAlignment="Top" Width="239" Content="Alt Text" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I swapped the content for this and it now works, I think it was having an issue with the Grid container:
<ListBox x:Name="listImages">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="102" HorizontalAlignment="Left" Name="imgThumb" Stretch="UniformToFill" VerticalAlignment="Top" Width="155" Source="{Binding ImageFilename, Converter={StaticResource ImageConverter}}" Margin="5" />
<StackPanel>
<dataInput:Label Height="19" HorizontalAlignment="Left" Name="lblAltText" VerticalAlignment="Top" Width="239" Content="Alt Text" />
<TextBox Height="23" HorizontalAlignment="Stretch" Name="txtAltText" VerticalAlignment="Top" Text="{Binding Alt}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

WPF : InputBindings on a StackPanel

I want to put a command on a ListBoxItem. The ListBoxItem use a DataTemplate composed of a StackPanel (containing an Image and a TextBlock, both using Binding). I want that the doubleclick on that ListBoxItem fire the command.
I have tried this :
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False">
</StackPanel>
</DataTemplate>
I have also tried to put the Command Resources on a StackPanel containing this StackPanel, without any change.
I am certain of my binding because when I put the InputBindings part on the TextBlock, it works.
Thanks
Try handling the event in the ListBox instead of the StackPanel:
<ListBox>
<ListBox.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</ListBox.Resources>
<ListBox.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</ListBox.InputBindings>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox>
My code finally looks like this :
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
Thanks anyway, Mr Poulin.

Resources