WPF Show buttons inside a selected ListItem - c#

I'm working with a WPF application to manage our main software's versions. This application has a ListBox, and I set the ListBox.DataTemplate to each ListBoxItem has a Label and 2 Buttons inside it.
The following code shows my ListBox code:
<ListBox Grid.Row="0" SelectedItem="{Binding Path=SelectedVersion}" ItemsSource="{Binding Path=PatchList, Mode=TwoWay}" d:DataContext="{d:DesignInstance {x:Type ViewModels:MainWindowViewModel}}"
SelectionMode="Single" IsSynchronizedWithCurrentItem="True" Margin="1" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedIndex="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding Path=VersionNumber}" HorizontalAlignment="Left" Foreground="#FFFFFF" FontSize="19" />
<Button Grid.Column="1" Width="25" Height="25" Template="{StaticResource OnMouseOverListBoxitem}" ToolTip="Release" Command="{Binding Path=DataContext.ReleaseVersionCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" HorizontalAlignment="Right" d:DataContext="{d:DesignInstance {x:Type ViewModels:MainWindowViewModel}}" CommandParameter="{Binding}">
<ContentControl Template="{StaticResource Release}" />
</Button>
<Button Grid.Column="2" Width="25" Height="25" Template="{StaticResource OnMouseOverListBoxitem}" ToolTip="Trash" Command="{Binding Path=DataContext.DeleteVersionCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" HorizontalAlignment="Right" d:DataContext="{d:DesignInstance {x:Type ViewModels:MainWindowViewModel}}" CommandParameter="{Binding}">
<ContentControl Template="{StaticResource Trash}" />
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The problem is that I would like to show the label and the buttons ONLY for the Selected ListBoxItem.
By the way, I'm using bindings, and if you see some different code it's because I'm also using MahApp.Metro for Windows8-style.
Any suggestions?
Thank you.

try this one.
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter1" />
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Fnts}" Grid.Row="0" SelectedItem="{Binding Path=SelectedVersion}"
SelectionMode="Single" IsSynchronizedWithCurrentItem="True" Margin="1" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedIndex="0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding}" />
<Button Content=" X " Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected, Converter={StaticResource BooleanToVisibilityConverter1}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

Related

How to disable listbox item underlined when ALT key is pressed in wpf

I have a Listbox with some string and int items. When ALT key is pressed the list items are unlined. I have set in ContentPresenter style like this, RecognizesAccessKey="False". But it is not working. Please anyone suggest me to fix this. The Listbox values are like this, T1_1.
MainWindow
<ListBox
x:Name="dropListBox"
Grid.Row="1"
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AllowDrop="True"
Background="#F8F8F8"
BorderThickness="0"
ItemContainerStyle="{StaticResource ListBoxItemStyle}"
ItemsSource="{Binding DetailsCollection}"
Style="{StaticResource ListBoxStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image
Grid.Column="0"
Width="23"
Height="23"
Source="{Binding State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource IntToImageSourceConverter}}" />
<Label
Grid.Column="1"
Content="{Binding Name}"
FontSize="12" />
<Label
Grid.Column="2"
HorizontalAlignment="Right"
HorizontalContentAlignment="Right"
Content="{Binding CurrentValue}"
FontSize="12" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

How do I bind ListItem to CommandParameter

I have a ListBox :
<ListBox Margin="10" Padding="10" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- Data template -->
<Grid>
<Grid.ColumnDefinitions>
<!--Image-->
<ColumnDefinition Width="auto" />
<!--Info-->
<ColumnDefinition Width="500" />
<!--Options-->
<ColumnDefinition Width="*" /
</Grid.ColumnDefinitions>
<Image Height="50" Width="50" />
<StackPanel Grid.Column="1" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Name}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ID: " />
<TextBlock Text="{Binding ID}" />
</StackPanel>
</StackPanel>
<Button Grid.Column="2" Content="{Binding Status}" Command="{Binding CompleteCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainPageViewModel}}}" CommandParameter="{Binding}" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I need my CommandParameter be the ListItem of this ListBox.
Set the AncestorType to ListBox and include DataContext in the path:
<Button ... Command="{Binding DataContext.CompleteCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" CommandParameter="{Binding}" HorizontalAlignment="Right"></Button>
Then the Command binding should work provided that the CompleteCommand property belongs to the same class as the Items property

Listbox item mouse double click only works on text not whole line

My ListBox uses this DataTemplate to act on LeftDoubleClick:
<UserControl x:Class="X1.XPrep.GuiModuleJobSelection.Views.ContentJobSelectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:l="http://wpflocalizeextension.codeplex.com"
xmlns:Classes="clr-namespace:X1.XPrep.GuiModuleJobSelection.Models"
xmlns:ViewModels="clr-namespace:X1.XPrep.GuiModuleJobSelection.ViewModels"
l:LocalizeDictionary.DesignCulture="en"
l:ResxLocalizationProvider.DefaultAssembly="XPrep.GuiModuleJobSelection"
l:ResxLocalizationProvider.DefaultDictionary="Resources"
x:Name="jobSelectionContent"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance {x:Type ViewModels:ContentJobSelectionViewModel}, IsDesignTimeCreatable=True}"
d:DesignHeight="600" d:DesignWidth="328.5">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/XPrep.GuiCommon;component/Resources/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:Key="ListboxJobDataTemplate" DataType="{x:Type Classes:JobForJobSelectionViewModel}">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding JobData.JobName}"
VerticalAlignment="Top">
<TextBlock.ToolTip>
<StackPanel Height="200" MinWidth="200">
<StackPanel Width="200" Orientation="Vertical" >
<TextBlock Text="{Binding JobData.JobName}" FontWeight="Bold"/>
<Image VerticalAlignment="Top" Source="{Binding PreviewImageSource}" Margin="0,10,0,0"/>
<TextBlock Text="No preview image available." Margin="0,10,0,0">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsPreviewImageMissing}" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="{Binding JobData.Comment}"/>
</StackPanel>
</StackPanel>
</TextBlock.ToolTip>
<TextBlock.InputBindings>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding Path=DataContext.LoadCommand,
RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}"/>
</TextBlock.InputBindings>
</TextBlock>
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Jobs, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedJob, Mode=TwoWay}" ItemTemplate="{DynamicResource ListboxJobDataTemplate}"
Grid.Column="1" Grid.Row="0" x:Name="listBoxJobNames" MinWidth="200"
HorizontalAlignment="Stretch" Margin="6" VerticalAlignment="Stretch">
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding Path=DataContext.DeleteCommand,
RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}"/>
</ListBox.InputBindings>
</ListBox>
<StackPanel Grid.Column="0" Grid.Row="0" Margin="0" Width="100" Background="{DynamicResource ContextBackgroundBrush}">
<Button x:Name="jobSelectionNewButton" Content="{DynamicResource X1.Job.New}" ToolTip="{l:Loc JobSelection_Button_New}"
HorizontalAlignment="Left" Margin="6" VerticalAlignment="Top" Command="{Binding NewCommand}" IsDefault="True"
Style="{StaticResource GlossyButtonX1}"/>
<Button Content="{DynamicResource X1.Job.Load}" ToolTip="{l:Loc JobSelection_Button_Load}"
HorizontalAlignment="Left" Margin="6" VerticalAlignment="Top"
Style="{StaticResource GlossyButtonX1}"
Command="{Binding LoadCommand}"/>
<Button Content="{DynamicResource X1.Job.Rename}" ToolTip="{l:Loc JobSelection_Button_Rename}"
HorizontalAlignment="Left" Margin="6" VerticalAlignment="Top"
Style="{StaticResource GlossyButtonX1}"
Command="{Binding RenameCommand}"/>
<Button Content="{DynamicResource X1.Job.Clone}" ToolTip="{l:Loc JobSelection_Button_Clone}"
HorizontalAlignment="Left" Margin="6" VerticalAlignment="Top"
Style="{StaticResource GlossyButtonX1}"
Command="{Binding CloneCommand}"/>
<Button Content="{DynamicResource X1.Common.Delete}" ToolTip="{l:Loc JobSelection_Button_Delete}"
HorizontalAlignment="Left" Margin="6" VerticalAlignment="Top"
Style="{StaticResource GlossyButtonX1}"
Command="{Binding DeleteCommand}"/>
</StackPanel>
</Grid>
The double click only works on the actual text in the items line.
What can I do, to let the double click also work on the empty spaces to the right of my item text?
Regards
Rainer
Set ListBoxItems' HorizontalContentAlignment = Stretch.
For example:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
In case, above code doesn't work, also try setting the Background of the Grid to Transparent (if you are using Grid):
<Grid Background="Transparent">
EDIT:
Bind TextBlock Width to ListBoxItem Width as shown below should fix the issue:
<TextBlock HorizontalAlignment="Left"
TextWrapping="Wrap"
Text="{Binding JobData.JobName}"
VerticalAlignment="Top"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=ActualWidth}">

Bind all Tab item view model at start in WPF

I have an application with 2 tabs which are Person and User Management in WPF with MVVM. Now the problem is when I click on Person Mag tab, the PersonViewModel will bind to Person Mag View, and User Mag same as mentioned situation also.
How to make Person and User Mag tab bind its view model at start of the application (both bind viewmodel for its own view at the same time) instead of bind the view model when I clicked on that tab.
XAML
<DockPanel LastChildFill="True">
<TabControl TabStripPlacement="Left" DockPanel.Dock="Left" Margin="5">
<TabItem Width="190" Margin="1">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Person-Management-Icon.png" Width="32" Height="32" />
<TextBlock Text="Person Mangement" Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
<TabItem.ContentTemplate>
<DataTemplate>
<ptab:PersonManagementView />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
<TabItem Margin="1">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/User-Management-Icon.png" Width="32" Height="32" />
<TextBlock Text="User Mangement" Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
<TabItem.ContentTemplate>
<DataTemplate>
<ptab:UserManagementView />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
</TabControl>
</DockPanel>
PersonManagement XAML
<!--View Model Section-->
<UserControl.DataContext>
<vm:PersonViewModel />
</UserControl.DataContext>
<!--End View Model Section-->
<!--Resources Section-->
<UserControl.Resources>
<ResourceDictionary Source="../Resources/ResourceDictionary.xaml" />
</UserControl.Resources>
<!--End Resources Section-->
<DockPanel Name="Person_Management_View">
<TabControl DockPanel.Dock="Top">
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Person-Creation-Icon.png" Width="24" Height="24" />
<TextBlock Text="Person Creation" Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
<Grid>
<Grid.RowDefinitions>
<!--Name-->
<RowDefinition Height="Auto" />
<!--Gender-->
<RowDefinition Height="Auto" />
<!--Department-->
<RowDefinition Height="Auto" />
<!--Error Message-->
<RowDefinition Height="25" />
<!--Save Button-->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--Name Section-->
<Label Grid.Row="0" Grid.Column="0" Content="Name"/>
<Label Grid.Row="0" Grid.Column="1" Content=":"/>
<TextBox Name="txtPersonName" Grid.Row="0" Grid.Column="2" Margin="4">
<TextBox.Text>
<Binding Path="PersonObject.Name" UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<r:PersonNameRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<!--End Name Section-->
<!--Gender Section-->
<Label Grid.Row="1" Grid.Column="0" Content="Gender"/>
<Label Grid.Row="1" Grid.Column="1" Content=":"/>
<ComboBox Grid.Row="1" Grid.Column="2" Margin="4" ItemsSource="{Binding GenderList}" SelectedItem="{Binding PersonObject.Gender}"/>
<!--End Gender Section-->
<!--Department Section-->
<Label Grid.Row="2" Grid.Column="0" Content="Department" />
<Label Grid.Row="2" Grid.Column="1" Content=":"/>
<ComboBox Grid.Row="2" Grid.Column="2" Margin="4" ItemsSource="{Binding DepartmentList}" SelectedItem="{Binding PersonObject.DepartmentName}" />
<!--End Department Section-->
<!--Error Message Section-->
<TextBlock Grid.Row="3" Grid.Column="2" Margin="4,4,4,0" Visibility="{Binding ElementName=txtPersonName, Path=(Validation.Errors), Converter={StaticResource toVisibilityConverter}}" Style="{StaticResource RedTextBlock}">
<TextBlock.Text>
<Binding ElementName="txtPersonName" Path="(Validation.Errors).CurrentItem.ErrorContent"/>
</TextBlock.Text>
</TextBlock>
<!--End Error Message Section-->
<!--Save Button Section-->
<Button Grid.Row="4" Grid.Column="2" HorizontalAlignment="Right" MinWidth="100" Margin="4,0,4,4" Content="Save" Command="{Binding CreatePersonCommand}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=txtPersonName, Path=(Validation.HasError)}" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<!--End Save Button Section-->
</Grid>
</TabItem>
</TabControl>
<!--Person Data Section-->
<DataGrid Name="PersonDataGrid" DockPanel.Dock="Bottom" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" ColumnWidth="*" ItemsSource="{Binding PersonList}">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding PersonID}" />
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Gender" Binding="{Binding Gender, Converter={StaticResource emptyStringConverter}}" />
<DataGridTextColumn Header="Department" Binding="{Binding DepartmentName, Converter={StaticResource emptyStringConverter}}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button IsEnabled="{Binding Selected, Converter={StaticResource oppositeBoolConverter}}" Command="{Binding DataContext.DeletePersonCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding PersonID}" Style="{StaticResource TransparentButton}">
<Image Source="{Binding Selected, Converter={StaticResource deleteImageConverter}}" Width="16" Height="16"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding DataContext.ViewPersonCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding PersonID}" Style="{StaticResource TransparentButton}">
<Image Source="/Images/Update-Icon.png" Width="16" Height="16"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<!--End Person Data Section-->
</DockPanel>
Try this
Add Loaded event to TabControl
<TabControl TabStripPlacement="Left" DockPanel.Dock="Left" Margin="5" Loaded="Tab_OnLoaded" >
Remove the ContentTemplate from xaml and assign content in code like
void Tab_OnLoaded(object sender, RoutedEventArgs e)
{
var tabControl = sender as TabControl;
if (tabControl != null)
{
for (int i = 0; i < tabControl.Items.Count; i++)
{
if (i == 1)
(tabControl.Items[i] as TabItem).Content = new UserControl2();//Here assign the Usercontrol that you want to set as Content
}
tabControl.Loaded -= Tab_OnLoaded; // Do this on first time only
}
}
I dont think its a good approach . I hope this will help.

How to access dynamic control WPF in DataTemplate

I created a tabcontrol with TabItem dynamic, and each TabItem with a button to close it, but just want that button visible when the TabItem is selected.
But I can not access the control inside the DataTemplate
<TabControl Name="dynamicTab" ItemsSource="{Binding}" Margin="0,85,0,0">
<TabControl.Resources>
<DataTemplate x:Key="TabHeader" DataType="TabItem">
<DockPanel>
<Button
Focusable="False"
BorderThickness="0"
Background="Transparent"
BorderBrush="Transparent"
Padding="-4"
Height="10"
Width="10"
Name="btnDelete" Visibility="Hidden" DockPanel.Dock="Right" Margin="5,0,0,0" Click="btnDelete_Click"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}">
<Image Name="imgButtonClose" Source="/Recursos;component/Imagens/close16x16.png" Height="10" Width="10"/>
</Button>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
</DockPanel>
</DataTemplate>
</TabControl.Resources>
</TabControl>
Just use the binding on the IsSelected property of ancestoral TabItem:
<BooleanToVisibilityConverter x:Key="boolToVisibilityConverter"/>
...
<Button ...
Name="btnDelete"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=IsSelected, Converter={StaticResource boolToVisibilityConverter}">
...
</Button>
If you have no problems with this binding:
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}"
then the proposed code should work.

Categories