WPF ListView Binding showing class namespace - c#

I have a ListView in my XAML defined as
<vm:JobListView x:Name="JobEditor" ItemsSource="{Binding Path=JobListViewSource}">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn Width="10" HeaderContainerStyle="{DynamicResource FirstColumnGridViewColumnHeader}" CellTemplate="{StaticResource EmptyColumnTemplate}" />
<vm:SortListViewColumn Header="Description" Width="100" SortProperty="Description" SortStyle="JobDataGridViewColumnHeader" CellTemplate="{StaticResource DescriptionColumnTemplate}" />
<vm:SortListViewColumn Header="Staff" Width="100" SortProperty="Staff.FirstName" SortStyle="JobDataGridViewColumnHeader" CellTemplate="{StaticResource StaffColumnTemplate}" />
<vm:SortListViewColumn Header="Client" Width="50" SortProperty="Client.Name" SortStyle="JobDataGridViewColumnHeader" CellTemplate="{StaticResource ClientColumnTemplate}" />
<vm:SortListViewColumn Header="Samples" Width="100" SortProperty="Samples" SortStyle="JobDataGridViewColumnHeader" CellTemplate="{StaticResource SamplesNoColumnTemplate}" />
<vm:SortListViewColumn Header="Entry Date" Width="100" SortProperty="EntryDate" SortStyle="JobDataGridViewColumnHeader" CellTemplate="{StaticResource EntryDateColumnTemplate}" />
<GridViewColumn Width="10" CellTemplate="{StaticResource EmptyColumnTemplate}" />
</GridView>
</ListView.View>
</vm:JobListView>
vm:JobListView is a class that inherits from ListView
The CellTemplates are defined like this:-
<!-- description column -->
<DataTemplate x:Key="DescriptionColumnTemplate">
<TextBox Style="{StaticResource ReadOnlyTextBlockStyle}" Text="{Binding Path=Description}" />
</DataTemplate>
The ItemsSource is bound to a property on my VM defined like this:-
public ICollectionView JobListViewSource
{
get { return Get(() => JobListViewSource); }
set { Set(() => JobListViewSource, value); }
}
and I set the property like this:-
CollectionViewSource source = new CollectionViewSource();
source.Source = this.Jobs;
this.JobListViewSource = source.View;
where Jobs is an ObservableCollection of Job objects
What I get displayed in my grid is just the namespace of the Job object and not the individual properties in each column
What am I doing wrong?

Try using
this.JobListViewSource.SourceCollection=this.Jobs instead of
CollectionViewSource source = new CollectionViewSource();
source.Source = this.Jobs;
this.JobListViewSource = source.View;

Related

ListView grouping - missing text (WPF, c#, XAML)

I'm trying display ListView grouping. I did as below:
ListView.xaml.cs
ListViewModel lvm = new ListViewModel();
lvUsers3.ItemsSource = lvm.getData();
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers3.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Type");
view.GroupDescriptions.Add(groupDescription);
ListView.xaml
<ListView Name="lvUsers3" Margin="0,197,94,0" ItemsSource="{Binding tvq}">
<ListView.View>
<GridView>
<GridViewColumn Header="FirstName" Width="100" DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="LastName" Width="100" DisplayMemberBinding="{Binding LastName}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="14" FontStyle="Normal" Text="{Binding Type}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
ListViewModel.cs
namespace LayoutMVVM.ViewModels
{
public class ListViewModel
{
public List<test_view> getData()
{
testViewClassDataContext tv = new testViewClassDataContext();
List<test_view> tvq = (from tt in tv.test_views
select tt).ToList();
return tvq;
}
}
}
On result I see that is grouped but the "type" value is missing (like was hidden?)
When you have applied the grouping you have created a group object that contains your sub items and this is what you are binding your group header to
the group object doesn't contain a Type property to bind to
try "{Binding Name}" instead of "{Binding Type}"

WPF ListView group and sort

I'm trying to group items on my list and sort them from oldest to newest. Grouping works perfect, it just doesn't want to inverse this list.
WPF Code:
<ListView x:Name="lst_orders" Margin="5" GridViewColumnHeader.Click="results_Click">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="IsSelected" Value="true" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button x:Name="goto_parts" Content="Show parts" Width="AUTO" Padding="2" Margin="2" Background="#FF179917" Click="goto_parts_Click"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Order ID" Width="100" DisplayMemberBinding="{Binding fullOrderId}" />
<GridViewColumn Header="Job Status" Width="100" DisplayMemberBinding="{Binding status}" />
<GridViewColumn Header="Order Type" Width="150" DisplayMemberBinding="{Binding orderType}" />
<GridViewColumn Header="Customer Notes" Width="250" DisplayMemberBinding="{Binding notes}" />
<GridViewColumn Header="Admin Notes" Width="250" DisplayMemberBinding="{Binding adminNotes}" />
<GridViewColumn Header="Production Notes" Width="100" DisplayMemberBinding="{Binding production_notes}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Gray">
<TextBlock Text="Days: " FontSize="18" FontWeight="Bold"/>
<TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold"/>
<TextBlock Text=" Systems: " FontSize="18" FontWeight="Bold"/>
<TextBlock Text="{Binding ItemCount}" FontSize="18" FontWeight="Bold"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
C# Code:
ICollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lst_orders.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("daysOld");
view.GroupDescriptions.Add(groupDescription);
view.SortDescriptions.Add(new SortDescription("daysOld", ListSortDirection.Descending));
lst_orders.ItemsSource = view;
daysOld is a property that calculates difference between today's date and order date, works perfect, but I want to see it from the highest number to the lowest. Picture shows what I get, and I want to reverse it.
Your code is correct.I've made a test. It is possible to see in view:
C#:
List<SomeClass> list = new List<SomeClass>();
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
list.Add(new SomeClass() { DaysOld = DateTime.Now.Add(new TimeSpan(0, rnd.Next(25), 0))});
}
ICollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(list);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("daysOld");
view.GroupDescriptions.Add(groupDescription);
view.SortDescriptions.Add(new SortDescription("DaysOld", ListSortDirection.Descending));
listBox.ItemsSource = view;
listBox.DisplayMemberPath = "DaysOld";
XAML:
<ListBox Name="listBox"/>
Model:
public class SomeClass
{
public DateTime DaysOld { get; set; }
}
Image:

how to access specific control in datatemplate generated listbox

So i have dataTemplate generated listbox like this:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Fill="{Binding color}" Height="10" Width="10" Grid.Column="1"/>
<TextBlock Text=" " Grid.Column="2"/>
<TextBlock Text="{Binding ID}" FontSize="10" FontWeight="Bold" Grid.Column="3"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate
and I bind it to ObservableCollection. I need to access specific item in this listbox and change colour of its rectangle element.
I would use a StyleSelector. make a styleselector like this:
ListViewItemStyleSelector.cs
public class ListViewItemStyleSelector : StyleSelector
{
public override Style SelectStyle(object item,
DependencyObject container)
{
Style st = new Style();
st.TargetType = typeof(ListViewItem);
Setter backGroundSetter = new Setter();
backGroundSetter.Property = ListViewItem.BackgroundProperty;
ListView listView =
ItemsControl.ItemsControlFromItemContainer(container)
as ListView;
int index =
listView.ItemContainerGenerator.IndexFromContainer(container);
if (index % 2 == 0) <-- here your own criteria
{
backGroundSetter.Value = Brushes.LightBlue;
}
else
{
backGroundSetter.Value = Brushes.Beige;
}
st.Setters.Add(backGroundSetter);
return st;
}
}
use of the styleselector
xaml
<ListView
ItemsSource="{Binding Source={StaticResource EmployeeData},
XPath=Employee}"
ItemContainerStyleSelector="{DynamicResource myStyleSelector}" >
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding XPath=FirstName}"
Header="First Name" Width="120"/>
<GridViewColumn DisplayMemberBinding="{Binding XPath=LastName}"
Header="Last Name" Width="120"/>
<GridViewColumn DisplayMemberBinding="{Binding XPath=FavoriteCity}"
Header="Favorite City" Width="120"/>
</GridView>
</ListView.View>
</ListView>

Rebind listview after insertion operation

We have a Listview. Inside that listview we have import button to import the data into SQL SERVER database.
After import of data if I tried to rebind the Listview, it does not reflect changes or rebind.
Below is my code snippet.
<Window x:Class="Searching.ImportedKeywords"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ImportedKeywords" Height="418.769" Width="1332.12" Background="#FFFBF6E3">
<Grid Margin="-1094,0,2,24" RenderTransformOrigin="0.621,0.497">
<Grid.RowDefinitions>
<RowDefinition Height="432*"/>
<RowDefinition Height="350*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="0*"/>
</Grid.ColumnDefinitions>
<ListView Name="lvShowSearching" Height="247" VerticalAlignment="Top" RenderTransformOrigin="2.25,3.86" Margin="1100,126,0,0" Grid.RowSpan="2">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name" Width="70" DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="Last Name" Width="70" DisplayMemberBinding="{Binding LastName}" />
<GridViewColumn Header="All Words" Width="100" DisplayMemberBinding="{Binding WithAllOfTheWords}" />
<GridViewColumn Header="Exact Phrase" Width="100" DisplayMemberBinding="{Binding WithTheExactPhrase}" />
<GridViewColumn Header="At Least One Word" Width="150" DisplayMemberBinding="{Binding WithAtLeastOneOfTheseWords}" />
<GridViewColumn Header="Without Word" Width="100" DisplayMemberBinding="{Binding WithoutTheWord}" />
<!--<GridViewColumn Header="Exact Date" Width="70" DisplayMemberBinding="{Binding ExactDate}" />
<GridViewColumn Header="Years" Width="70" DisplayMemberBinding="{Binding StartYear}" />
<GridViewColumn Header="Start Date" Width="70" DisplayMemberBinding="{Binding StartDate}" />
<GridViewColumn Header="End Date" Width="70" DisplayMemberBinding="{Binding EndDate}" />-->
<GridViewColumn Header="Country" Width="70" DisplayMemberBinding="{Binding CountryName}"/>
<GridViewColumn Header="State" Width="70" DisplayMemberBinding="{Binding StateName}" />
<GridViewColumn Header="City" Width="70" DisplayMemberBinding="{Binding CityName}" />
<GridViewColumn Header="Publication" Width="70" DisplayMemberBinding="{Binding PublicationName}" />
<GridViewColumn Header="Total Records" Width="100" DisplayMemberBinding="{Binding TotalRecords}" />
<GridViewColumn Header="Records Imported" Width="100" DisplayMemberBinding="{Binding TotalRecordsImported}" />
<GridViewColumn Header="Status" Width="70" DisplayMemberBinding="{Binding Status}" />
<GridViewColumn Header="Records To Import" Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="70" Name="txtRecordsToImport" Text="{Binding RecordsToImport}"></TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Import" Width="70">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Click="Import_Click">Import</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Image HorizontalAlignment="Left" Source="Images/logonav2.png" Height="100" Margin="1100,5,0,0" VerticalAlignment="Top" Width="1190"/>
</Grid>
</Window>
Code of import button:
private void Import_Click(object sender, RoutedEventArgs e)
{
DateFilter dateFilter = new DateFilter();
SearchRequest objSearchRequest = new SearchRequest();
ListViewItem grvRow = FindVisualParent<ListViewItem>(sender as UIElement);
if (grvRow != null)
{
ClippingSearchKeyword objSearch = ((ClippingSearchKeyword)(grvRow).Content);
if (objSearch.RecordsToImport == 0)
{
MessageBox.Show("Please enter records to import.");
return;
}
objSearchRequest.LocationFilter.CitiesString = Convert.ToString(objSearch.CityID);
objSearchRequest.LocationFilter.CountriesString = Convert.ToString(objSearch.CountryID);
objSearchRequest.LocationFilter.StatesString = Convert.ToString(objSearch.StateID);
objSearchRequest.LocationFilter.PublicationsString = Convert.ToString(objSearch.PublicationID);
objSearchRequest.FirstName = objSearch.FirstName;
objSearchRequest.LastName = objSearch.LastName;
objSearchRequest.AllOfTheWordsString = objSearch.WithAllOfTheWords;
objSearchRequest.WithoutWordsString = objSearch.WithoutTheWord;
objSearchRequest.ExactPhraseString = objSearch.WithTheExactPhrase;
objSearchRequest.AnyOfTheWordsString = objSearch.WithAtLeastOneOfTheseWords;
objSearchRequest.AllOfTheWordsString = objSearch.WithAllOfTheWords;
if (objSearch.ExactDate != null)
{
dateFilter.SetExactDateFilter(objSearch.ExactDate.Value);
objSearchRequest.DateFilters.Add(0, dateFilter);
}
else if (objSearch.StartDate != null)
{
dateFilter.SetBetweenDatesFilter(objSearch.StartDate.Value, objSearch.EndDate.Value);
objSearchRequest.DateFilters.Add(0, dateFilter);
}
else if (true)
{
dateFilter.SetBetweenYearsFilter(objSearch.StartYears.Value, objSearch.EndYear.Value);
objSearchRequest.DateFilters.Add(0, dateFilter);
}
int count = new AdvancedSearching().SearchContent(objSearchRequest, objSearch.TotalRecords, objSearch.TotalRecordsImported, objSearch.RecordsToImport, objSearch.KeywordID);
if (count == 0)
{
MessageBox.Show("No record found to import.");
}
else
{
MessageBox.Show(count + " Record(s) imported successfully.");
BindList();
}
}
}
BindList(); is the method to bind listview.
public void BindList()
{
var data = objCommon.GetSearchKeywords();
lvShowSearching.ItemsSource = data;
}
Also please suggest a way to design this grid in better way. I am basically a web developer but have been working on WPF for last 2-3 days.
use
<ListView Name="lvShowSearching" Height="247" VerticalAlignment="Top" RenderTransformOrigin="2.25,3.86" Margin="1100,126,0,0" Grid.RowSpan="2" ItemsSource={Binding Path=.}>
instead of
<ListView Name="lvShowSearching" Height="247" VerticalAlignment="Top" RenderTransformOrigin="2.25,3.86" Margin="1100,126,0,0" Grid.RowSpan="2">
and in code behind
use
lvShowSearching.UpdateLayout();
after
lvShowSearching.ItemSource=data

How to get row data of each column if button is clicked inside listview

I am new to WPF. I have just bind one listview. Under my listview there is a button in each row.
When user clicks on that button, the data from that particular row should be fetched.
Below is my code
<Window x:Class="Searching.ImportedKeywords"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ImportedKeywords" Height="330.769" Width="1079.12">
<Grid Margin="-1094,0,2,24" RenderTransformOrigin="0.621,0.497">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="0*"/>
</Grid.ColumnDefinitions>
<ListView Name="lvShowSearching" Height="247" VerticalAlignment="Top" RenderTransformOrigin="2.25,3.86" Margin="1100,10,0,-13">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name" Width="70" DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="Last Name" Width="70" DisplayMemberBinding="{Binding LastName}" />
<GridViewColumn Header="With All Of The Words" Width="100" DisplayMemberBinding="{Binding WithAllOfTheWords}" />
<GridViewColumn Header="With The Exact Phrase" Width="100" DisplayMemberBinding="{Binding WithTheExactPhrase}" />
<GridViewColumn Header="With At Least One Of These Words" Width="100" DisplayMemberBinding="{Binding WithAtLeastOneOfTheseWords}" />
<GridViewColumn Header="Without The Word" Width="100" DisplayMemberBinding="{Binding WithoutTheWord}" />
<GridViewColumn Header="Country" Width="70" DisplayMemberBinding="{Binding CountryName}"/>
<GridViewColumn Header="State" Width="70" DisplayMemberBinding="{Binding StateName}" />
<GridViewColumn Header="City" Width="70" DisplayMemberBinding="{Binding CityName}" />
<GridViewColumn Header="Publication" Width="70" DisplayMemberBinding="{Binding PublicationName}" />
<GridViewColumn Header="Total Records" Width="70" DisplayMemberBinding="{Binding TotalRecords}" />
<GridViewColumn Header="Total Records Imported" Width="70" DisplayMemberBinding="{Binding TotalRecordsImported}" />
<GridViewColumn Header="Status" Width="70" DisplayMemberBinding="{Binding Status}" />
<GridViewColumn Header="Import" Width="70">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button CommandParameter="{Binding}" Click="Button_Click_1">Import</Button>
<!--<TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />-->
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Address">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Margin="6,2,6,2">
<Button Content="Address"
Command="{Binding
Path=DataContext.RunCommand,
RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type ItemsControl}}}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
private void Button_Click_1(object sender, RoutedEventArgs e)
{
IEnumerable items = this.lvShowSearching.Items;
foreach (ClippingSearchKeyword data in items)
{
if (data != null)
{
}
}
}
private void OnRunCommand(object obj)
{
if (obj != null)
{
}
}
You can find your parent GridViewRow using below method
public static T FindVisualParent<T>(UIElement element) where T : UIElement
{
UIElement parent = element;
while (parent != null)
{
T correctlyTyped = parent as T;
if (correctlyTyped != null)
{
return correctlyTyped;
}
parent = VisualTreeHelper.GetParent(parent) as UIElement;
}
return null;
}
And change ButtonClick event as below,You will get GridViewRow
private void Button_Click_1(object sender, RoutedEventArgs e)
{
GridViewRow grvRow= FindVisualParent<GridViewRow>(sender as UIElement);
}

Categories

Resources