XAML binding behaviour on ListView inside ListView data binding - c#

I have a class
Class Test
{
string name {get;set;}
List<string> marks {get; set;}
}
Trying to bind data of ObservableCollection to XAML
<ListView x:Name="list1" HorizontalAlignment="Left" VerticalAlignment="Top" ItemsSource="{Binding}" Width="790">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<GridViewColumn Header="Name" HeaderTemplate="{StaticResource myHeaderTemplate}" HeaderContainerStyle="{StaticResource myHeaderStyle}" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="xyt" Text="{Binding name}" TextAlignment="Center" FontFamily="Arial" FontSize="14">
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Marks" HeaderTemplate="{StaticResource myHeaderTemplate}" HeaderContainerStyle="{StaticResource myHeaderStyle}" Width="500">
<GridViewColumn.CellTemplate>
<DataTemplate>
**<ListView x:Name="list2" ItemsSource="{Binding marks}">
<DataTemplate>
<TextBlock x:Name="marki" Text="{Binding}" TextAlignment="Center" FontFamily="Arial" FontSize="16" Margin="10" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown">
</TextBlock>
</DataTemplate>
</ListView>**
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
But I get error in binding "operation-is-not-valid-while-itemssource-is-in-use-access"
When I remove DataTemplate from list2, it shows properly with data binding, with name and corresponding listview of marks.
<ListView x:Name="list1" HorizontalAlignment="Left" VerticalAlignment="Top" ItemsSource="{Binding}" Width="790">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<GridViewColumn Header="Name" HeaderTemplate="{StaticResource myHeaderTemplate}" HeaderContainerStyle="{StaticResource myHeaderStyle}" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="xyt" Text="{Binding name}" TextAlignment="Center" FontFamily="Arial" FontSize="14">
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Marks" HeaderTemplate="{StaticResource myHeaderTemplate}" HeaderContainerStyle="{StaticResource myHeaderStyle}" Width="500">
<GridViewColumn.CellTemplate>
<DataTemplate>
**<ListView x:Name="list2" ItemsSource="{Binding marks}">
</ListView>**
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I am assigning datasource as
list1.ItemsSource = observablecollection<Test>;
I tried adding giving Path, relativesource, but still facing error.
I am confused why putting TextBlock causing error?

you are missing <ListView.ItemTemplate> tag around DataTemplate:
<ListView x:Name="list2" ItemsSource="{Binding marks}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="marki" Text="{Binding}" TextAlignment="Center" FontFamily="Arial" FontSize="16" Margin="10" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
</DataTemplate>
<ListView.ItemTemplate>
</ListView>
markup
<ListView>
<DataTemplate>
</DataTemplate>
</ListView>
is equivalent to
<ListView>
<ListView.Items>
<DataTemplate>
</DataTemplate>
<ListView.Items>
</ListView>
and Items usage conflicts with setting ItemsSource.
<ListView.Items> can be omitted because Items property is chosen as ContentProperty for ListView.

Related

Cannot Bind Grouping property in ListView

I have an ObservableCollection of items that I want to use to group my ListView, but I just can't bind my Grouping to that item.
That's my little class:
public class Module
{
public string Name { get; set; }
public Module(string name)
{
Name = name;
}
}
ViewModel:
public ObservableCollection<Module> ServerModules
{
get => serverModules;
set
{
if (serverModules == value) { return; }
serverModules = value;
OnPropertyChanged();
}
}
Here my Xaml Code:
<StackPanel Orientation="Vertical">
<ListView ItemsSource="{Binding ServerModules}">
<ListView.View>
<GridView>
<GridViewColumn Header="Property" Width="200"/>
<GridViewColumn Header="Value" Width="200"/>
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontSize="20" FontWeight="Bold" Foreground="DodgerBlue" Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</StackPanel>
The Name Property cannot be resolved.
I also tried using a CollectionViewSource but it's also not working for me:
<CollectionViewSource x:Key="GroupModules" Source="{Binding ServerModules}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Name"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<ListView ItemsSource="{Binding Source={StaticResource GroupModules}}">
Any ideas and help are really appreciated.
Update Solution:
In my Resources section I defined a CollectionViewSource to set a GroupDescription property and a Style for my GroupItem.
<UserControl.Resources>
<CollectionViewSource x:Key="GroupedModules" Source="{Binding ServiceModuleSetViewModel.AllModuleProperties}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ModuleName" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<!-- ListView GroupStyle.ContainerStyle -->
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock Text="{Binding Name}" FontSize="13" Foreground="DodgerBlue" FontWeight="Bold" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
ListView:
<ListView ItemsSource="{Binding Source={StaticResource GroupedModules}}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.GroupStyle>
<GroupStyle/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="local:ModuleProperty">
<TextBlock FontSize="13" Text="{Binding Path=Name}" TextAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Value" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="local:ModuleProperty">
<TextBox FontSize="13" Text="{Binding Path=Value}" TextAlignment="Center"
Width="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
The ListView control has the CollectionViewSource Resource as ItemsSource.
Each GridViewColumn has a CellTemplate to display my data in the columns.
You need to define style for GroupItem or specify GroupStyle.ContainerStyle
Also for GridViewColumn you need to specify DisplayMemberBinding.
<UserControl.Resources>
<!-- ListView GroupStyle.ContainerStyle -->
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock Text="{Binding Name}" Foreground="Gray" FontWeight="Bold" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel Orientation="Vertical">
<ListView ItemsSource="{Binding ServerModules}">
<ListView.GroupStyle>
<GroupStyle/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Property" DisplayMemberBinding="{Binding Property}" Width="200"/>
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}" Width="200"/>
</GridView>
</ListView.View>
</ListView>
</StackPanel>

Edit and search item in listview

is there any control like jquery datatable in WPF for searching item from listview or how i can implement efficient search in listvew.
secondly, I have an image and title in listview control. How can I add "edit functionality" to change image Title.
I don't have any clue about it because I'm new in WPF. how I can perform this task. any example or useful code will be helpfull for me.
<ListView Name="lvDataBinding">
<ListView.View>
<GridView >
<GridViewColumn >
<GridViewColumn.CellTemplate>
<DataTemplate >
<StackPanel Margin="20,5,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<Image Margin="15,5,0,0" Style="{StaticResource PopupImageStyle}" HorizontalAlignment="Center" Width="60" ToolTip="{Binding Name}" Height="60" Source="{Binding ImgPath}"></Image>
<TextBlock Visibility="Hidden" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn >
<GridViewColumn.CellTemplate>
<DataTemplate >
<StackPanel Margin="20,5,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding Title}">
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.FontSize" Value="20"></Setter></Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--<GridViewColumn DisplayMemberBinding="{Binding Name}" />-->
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>

How to Style a cell in Gridview under ListView

How to style every cell in Gridview.I want my cell text in a rounded text box with red background.My code is
<ListView Margin="0" ItemsSource="{Binding ParamList}" >
<ListView.View >
<GridView >
<GridView.ColumnHeaderTemplate>
<DataTemplate>
<Border BorderThickness="2" CornerRadius="5" Height="75" MinWidth="60" >
<Border.Background>Gray</Border.Background>
<TextBlock Foreground="WhiteSmoke" Margin="5"
Text="{Binding}" Width="Auto"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</DataTemplate>
</GridView.ColumnHeaderTemplate>
<GridViewColumn Header="category1" DisplayMemberBinding="{Binding Path=param1}" />
<GridViewColumn Header="category2" DisplayMemberBinding="{Binding Path=param1}" />
</GridView>
</ListView.View>
</ListView>
Use the GridViewColumn's CellTemplate property to set a DataTemplate containing a TextBox with the appropriate styling for each of your columns. I don't believe there is a way to set it at the Gridview level so that you don't have to set it on each column individually.
<Grid>
<ListView ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="Red" Text="{Binding Item1}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Item2}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Grid>

How to center a TextBlock within a CellTemplate in WPF?

I tried both HorizontalAlignment and TextAlignment but it has no effect.
<GridViewColumn Width="Auto" Header="Type">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}" HorizontalAlignment="Center" TextAlignment="Center" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Any ideas?
EDIT:
Xaml code:
<Window x:Class="EffectsWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Effects Editor"
<DockPanel VerticalAlignment="Stretch">
<DockPanel.Resources>
<ListView
DockPanel.Dock="Top"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding EditorViewModel.AllEffects}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Name}"
Header="Name" />
<GridViewColumn Width="Auto" Header="Type">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}" HorizontalAlignment="Center" TextAlignment="Center" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<DockPanel Width="100"
Height="100"
Margin="0,0,20,20"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<Label Margin="0,0,0,0"
Content="Data"
DockPanel.Dock="Top" />
<ListBox
VerticalAlignment="Top"/>
</DockPanel>
</DockPanel>
</Window>
did you try HorizontalContentAlignment? on the column?
-- EDIT --
turns out it's kinda hard to find the right place to put this HorizontalContentAlignment... :)
use this
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</ListView.Resources>
in the listview.
Snoop usually helps u to be on the right path. This ContentPresenter is the used by the ListViewItem, and it gets its Alignment from the ContentAlignment on the ListViewItem. u can't access the ListViewItem directly, and that's why u need that Style
and the full code:
<DockPanel VerticalAlignment="Stretch">
<ListView
DockPanel.Dock="Top"
HorizontalContentAlignment="Stretch"
x:Name="MyListView">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView >
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Name}"
Header="Name" />
<GridViewColumn Width="Auto" Header="Type">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}" HorizontalAlignment="Center" TextAlignment="Center" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<DockPanel Width="100"
Height="100"
Margin="0,0,20,20"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<Label Margin="0,0,0,0"
Content="Data"
DockPanel.Dock="Top" />
<ListBox
VerticalAlignment="Top"/>
</DockPanel>
</DockPanel>
Unfortunatelly there is no way to adjust the horizontal alignment of TextBlocks within CellTemplate.
Because GridViewRowPresenter sets the HorizontalAlignment property of Cells to HorizontalContentAlignment of its TemplatedParent, which in this case is ListViewItem.
So you are going to have to change your ListViewItemStyle.
If you change the HorizontalContentAlignment of ListViewItem using snoop, you will see that the alignment of cell will not be affected since HorizontalContentAlignment value is set during the creating of the cells.

Add lines to gridview

I'm trying add vertical lines to my grid. I have found some examples but nothing works.
<ListView ItemsSource="{Binding Path=CheckableObjectFacilities}" x:Name="ListViewObjectFacilities" Margin="5">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsChecked}" Click="cboxObjectFacilities_Click" HorizontalContentAlignment="Stretch"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Nazwa" >
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Category}" Header="Kategoria" >
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding EnglishName}" Header="EN" ></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Created lines in your GridView by following the example from the following site: Designer WPF.
Here is some XAML I adapted to display system font information:
<Grid>
<Grid.Resources>
<Style x:Key="MyItemContainerStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</Grid.Resources>
<ListView
ItemContainerStyle="{DynamicResource MyItemContainerStyle}"
ItemsSource="{x:Static Fonts.SystemFontFamilies}"
x:Name="myListView"
Width="Auto">
<ListView.View>
<GridView>
<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border BorderBrush="#FF000000" BorderThickness="1,1,0,0" Margin="-6,-2,-6,-2">
<StackPanel Margin="6,2,6,2">
<TextBlock Text="{Binding Source}"/>
</StackPanel>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Line Spacing">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border BorderBrush="#FF000000" BorderThickness="1,1,0,0" Margin="-6,-2,-6,-2">
<StackPanel Margin="6,2,6,2">
<TextBlock Text="{Binding LineSpacing}"/>
</StackPanel>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Sample">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border BorderBrush="#FF000000" BorderThickness="1,1,1,0" Margin="-6,-2,-6,-2">
<StackPanel Margin="6,2,6,2">
<TextBlock FontFamily="{Binding}" FontSize="20"
Text="ABCDEFGabcdefg" />
</StackPanel>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>

Categories