Hide HeaderContent from the top of a ListView - wpf

I have a
<DockPanel>
<!-- Header -->
<Button DockPanel.Dock="Top" Command="{Binding CreateAccountCommand}" Margin="{StaticResource ControlMargin}" Style="{StaticResource IconButtonStyle}">
<StackPanel>
<MahAppsIconPacks:PackIconFontAwesome Kind="Pencil" />
<TextBlock>create account</TextBlock>
</StackPanel>
</Button>
<!-- Accounts list -->
<ListView SelectionMode="Single" SelectedIndex="0" ItemsSource="{Binding AccountViewModels}" SelectedItem="{Binding SelectedItem}" Style="{StaticResource AccountsList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<LocalViews:AccountView Margin="{StaticResource ControlMargin}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</DockPanel>
It renders with a black separator on top of it, which is quite ugly. How do I hide it? I have tried setting different styles, but there is no ListViewColumnHeader.
In the live tree it shows as header content ... not separator, my bad. How do I remove it?
This doesn't work:
<Style TargetType="ListView" x:Key="AccountsList" BasedOn="{StaticResource {x:Type ListView}}">
<Style.Resources>
<Style TargetType="HeaderedContentControl">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</Style.Resources>
</Style>

Are you using any of the View capabilities of ListView? (e.g. GridView etc which I believe is the default. In which case, the separator is probably the header section, but empty). If you're not, try just using a ListBox instead. It has no header as default.
Edit: I just checked this theory, but it appears I can't reproduce your issue at all. Here's a ListBox as you've got your code (and a ListView for good measure):
<Window.Resources>
<x:Array x:Key="Items" Type="sys:String">
<sys:String>Item 1</sys:String>
<sys:String>Item 2</sys:String>
<sys:String>Item 3</sys:String>
</x:Array>
</Window.Resources>
<StackPanel Margin="20">
<TextBlock Text="ListBox:"/>
<ListBox Height="100" ItemsSource="{StaticResource Items}" BorderBrush="Transparent">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
<TextBlock Text="ListView:"/>
<ListView Height="100" ItemsSource="{StaticResource Items}" BorderBrush="Transparent">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</StackPanel>
It may be the different themes on Windows 7 however, I'm using Windows 10.

I believe this is a result of the MahApps template. It's not the default behaviour of a standard WPF ListView.
You would have to adjust the MahApps template to get rid of it.
Something like this:
<Style TargetType="{x:Type ListView}" BasedOn="{StaticResource {x:Type ListView}}">
<Setter Property="BorderThickness" Value="0" />
</Style>
The MahApps code and resources are all open source. I think the particular problem you are having is driven by the BorderThickness setter here:
https://github.com/MahApps/MahApps.Metro/blob/develop/src/MahApps.Metro/MahApps.Metro/Styles/Controls.ListView.xaml
<Style x:Key="MetroListView" TargetType="{x:Type ListView}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="Background" Value="{DynamicResource WhiteBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BlackBrush}" />
<Setter Property="BorderThickness" Value="0 1 0 0" />

Related

How to setup a template for a ListBox with a DataTemplate

So I have the following ListBox defined:
<ListBox Grid.Row="1" Grid.Column="0" x:Name="RawLBControl"
ItemsSource="{Binding ProductionLists.Raw}"
Background="LightGray" BorderThickness="2" BorderBrush="Black">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
There are going to be a number of these, where the only things that changes is the placement (Grid location) and the ItemsSource bindings. Everything else is going to be the same. Question is how do I setup a template so all the ListBoxes use it.
You can define style in application resources and applied it to ListBox later in your code.
<Application x:Class="Q52018469.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyListBoxStyle" TargetType="ListBox">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
Using of this style:
...
<Grid>
...
<ListBox Grid.Row="1" Grid.Column="0" x:Name="RawLBControl"
ItemsSource="{Binding ProductionLists.Raw}"
Style="{StaticResource MyListBoxStyle}" />
</Grid>
...

Unable to disable textblock text in the itemtemplate

<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<StackPanel Orientation="Horizontal" Width="150" >
<TextBlock MaxWidth="125" Name="name" Text="{Binding name}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Margin="0,4,4,4" />
</StackPanel>
<Button Command="{buttontext}" Visibility="{Binding IsAvailable, Converter={uil:BoolToVisibilityConverter}}">
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="{Binding Isenable}"/>
</Style>
</ListBox.ItemContainerStyle>
I am unable to disable the text(Grey out) but as for the button is working fine.
Do anyone know how to solve this issue?
Hi Chris, i have referred to the link. i tried using
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding name}" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
but it is still not working. have any idea on this?
TextBlock doesn't support IsEnabled. The easiest fix would be to change your TextBlock to a Label

WPF MVVM Light Databinding a context menu to list view items

I am fairly new to WPF MVVM so please have some patience. I have a ListView with a list of users and I want to add a ContextMenu to this ListView. The ContextMenu should have the ability to edit whichever user you click on in the ListView. I will show you the code I currently have, sketched out. I know it doesn't work at the moment, but the basic idea is I need the UserID from the ListView row AND the information that is selected in the ContextMenu.
<ListView ItemsSource="{Binding ListViewItems}" SelectionMode="Single">
<ListView.ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Test" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}" />
<Separator></Separator>
<MenuItem Header="Status" ItemsSource="{Binding DataContext.ObservableCollectionList}" DisplayMemberPath="Name">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding DataContext.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}"/>
<Setter Property="CommandParameter" Value="{Binding}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ListView.ContextMenu>
//users and stuff here
</ListView>
So my question is really two fold:
How do I attached the ContextMenu to individual ListView items.
How do I pass the ListViewItem object AND the ContextMenu selected object in to the ViewModel RelayCommand?
Or, is there a better way to do this?
UPDATED CODE:
I have tried both of the suggestions below but neither works. I am going to supply the rest of the code that was already there, fully. Keep in mind, this comes AFTER the tag.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0"></Setter>
<Setter Property="Margin" Value="0"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<ItemContainerTemplate>
<Border BorderThickness="0,0,0,2" BorderBrush="LightGray">
<Grid>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="0.5">
<GradientStop Color="White"/>
<GradientStop Color="#FFDFE9F5" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Status}" FontStyle="Italic" Padding="0,0,0,3">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOnDuty}" Value="False">
<Setter Property="Opacity" Value="0.3" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</Border>
</ItemContainerTemplate>
</ListView.ItemTemplate>
you can make use of Styles to inject ContextMenu on individual ListViewItems
this is how you can set the style
<ListView ItemsSource="{Binding ListViewItems}"
SelectionMode="Single">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding Path=PlacementTarget.ListView.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Test"
Command="{Binding TestCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" />
<Separator></Separator>
<MenuItem Header="Status"
ItemsSource="{Binding ObservableCollectionList}"
DisplayMemberPath="Name">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command"
Value="{Binding DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}" />
<Setter Property="CommandParameter"
Value="{Binding}" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
</ListView>
unless a context menu is necessary on the main ListView you may remove ListView.ContextMenu
you may need to do the adjustments as needed as I did it based on some assumptions about the view model.
This is just another way of doing things.
If you don't want the ContextMenu to be in your ListView definition you could use this
<ContextMenu x:Key="ContextMenu" DataContext="{Binding Path=PlacementTarget.ListView.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Test" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" />
<Separator></Separator>
<MenuItem Header="Status" ItemsSource="{Binding ObservableCollectionList}"
DisplayMemberPath="Name">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}" />
<Setter Property="CommandParameter" Value="{Binding}" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
<ListView ItemsSource="{Binding ListViewItems}"
SelectionMode="Single">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="ContextMenu" Value="{StaticResource ContextMenu}">
</Setter>
</Style>
</ListView.Resources>
Although personally I prefer to use
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
This way you can easily switch between different ContextMenus.

Conditional DataTemplate

Here is what I am trying to do. I have 2 Data Templates defined which both refer to a different user control.
<UserControl.Resources>
<DataTemplate x:Key="myDataTemplate1">
<Border BorderBrush="Black" BorderThickness="1">
<myUserControl1 />
</Border>
</DataTemplate>
<DataTemplate x:Key="myDataTemplate2">
<Border BorderBrush="Black" BorderThickness="1">
<myUserControl2/>
</Border>
</DataTemplate>
</UserControl.Resources>
I am using these Data Templates to display a list of items using ItemsControl like this:
<ItemsControl x:Name="myItemList" ItemTemplate="{StaticResource myDataTemplate1}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate />
</ItemsControl.ItemsPanel>
</ItemsControl>
I would like the ItemTemplate to conditionally be either myDataTemplate1 or myDataTemplate1 depending on the value of an integer variable being 1 or 2 respectively.
Should I use DataTriggers for this or is there another way to do this? Appreciate the help.
Don't set the ItemTemplate but use an ItemTemplateSelector.
DataTriggers would be fine too of course, spares you the extra class for the selector. e.g.
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ThatProperty}" Value="1">
<Setter Property="ContentTemplate"
Value="{StaticResource myDataTemplate1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ThatProperty}" Value="2">
<Setter Property="ContentTemplate"
Value="{StaticResource myDataTemplate2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>

WPF ContentPresenter only showing first item in list

I am trying to create a WPF application where I have a StackPanel that shows a list of accounts. There is an Account object in the code behind for each account, stored in a List structure. I want to databind this to my WPF, but I don't want a listbox.
Instead, I defined a template for how each account summary should appear. I then want to stack these in a StackPanel and call it a day.
The problem is that the Data Binding only takes the first item from the list and that's it. How to I bind it so that this effectively creates a little stacked list of nicely formatted chunks of data?
Here is the relevant WPF code:
<StackPanel Name="sp_AccountList" Margin="0,0,0,0" VerticalAlignment="Top">
<StackPanel.Resources>
<svc:AccountBalanceColorConverter x:Key="accountColorConverter" />
<Style x:Key="AccountSummaryBackgroundGradient" TargetType="{x:Type StackPanel}">
<!-- nice formatting code here -->
</Style>
<Style x:Key="AccountSummaryNameStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="10,0,0,0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Height" Value="20" />
<Setter Property="FontFamily" Value="Cambria" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Transparent" />
</Style>
<Style x:Key="AccountSummaryBalanceStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="10,0,0,0" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Height" Value="20" />
<Setter Property="FontFamily" Value="Cambria" />
<Setter Property="Background" Value="Transparent" />
</Style>
<ObjectDataProvider x:Key="accounts"
ObjectType="{x:Type svc:AccountService}"
MethodName="ListAccounts" />
<DataTemplate x:Key="AccountSummaryLayout">
<StackPanel Orientation="Vertical" Style="{StaticResource AccountSummaryBackgroundGradient}">
<TextBlock Text="{Binding Path=Name}" Style="{StaticResource AccountSummaryNameStyle}" />
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{Binding Path=TotalAccountBalance, Converter={StaticResource accountColorConverter} }" Text="{Binding Path=TotalAccountBalance, Mode=OneWay}" Style="{StaticResource AccountSummaryBalanceStyle}" />
<TextBlock Foreground="{Binding Path=AvailableAccountBalance, Converter={StaticResource accountColorConverter} }" Text="{Binding Path=AvailableAccountBalance, Mode=OneWay}" Style="{StaticResource AccountSummaryBalanceStyle}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</StackPanel.Resources>
<StackPanel Orientation="Vertical">
<ContentPresenter x:Name="AccountSummaryPresenter" ContentTemplate="{StaticResource AccountSummaryLayout}" Content="{DynamicResource accounts}" />
</StackPanel>
</StackPanel>
StackPanel does not have an ItemsSource property, its children controls are not databindable.
What you can do is create an ItemsControl which uses a StackPanel as its Itemshost.
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Source={StaticResource accounts}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
...
</ItemsControl.ItemTemplate>
</ItemsControl>
<ScrollViewer>

Resources