How to bind DataTable to Datagrid? - wpf

I have a problem binding a DataTable to a Gridview. I have already searched for solutions but just can't get rid of the error. The bindwing works fine when using WindowsForms, so the DataTable is correct. I just can't bind it to a WPF Gridview.
XAML:
<ListView x:Name="listView1" ItemsSource="{Binding phnDirectory}"
C#
DataTable phnDirectory = obj.Getphone_directory();
listView1.ItemsSource = phnDirectory;
But it says "can not convert datatable to Collection.IEnumerables"
so what is the solution?
thanks in advance

Use this listView1.ItemsSource = phnDirectory.DefaultView

XAML:
<ListView Name="listView1" ItemsSource="{Binding}">
C#
DataTable phnDirectory = obj.Getphone_directory();
listView1.DataContext = phnDirectory.DefaultView;

A DataTable doesn't enumerate.
This is because what do you want to enumerate ? Columns, Rows, Constraints, Properties? you either need to tell it which you want to enumerate or link to the DataView via DefaultView
e.g.
<ListView x:Name="listView1" ItemsSource="{Binding phnDirectory.DefaultView }"
or
<ListView x:Name="listView1" ItemsSource="{Binding phnDirectory.Columns}"
in windows forms a datagrid is locked into showing Tables, a WPF GridView is merely a formatting note that says you want to view the data in a grid style there is no conversion on data

Related

Can't filter a Detail-table which is bound to a Master-table with rowfilter?

If I want to filter a detail table(shown in a DataGrid) by using for example something like this: DSHistory.TBL_MATERIAL.DefaultView.RowFilter = string.Format("MAT_NAME LIKE '%{0}%' AND MAT_FK_LFR_ID = {1}",TextBoxSearch.Text, ComboBoxLieferant.SelectedValue); it only works if I explicitly change the ItemsSource of the DataGrid to: dg1.ItemsSource = DSHistory.TBL_MATERIAL; in the event, but then the binding won't work any more(in page_loaded I added the DataContext like this: this.DataContext = DSHistory.TBL_LIEFERANTENSTAMM; and of course bind the master- and detail-table in XAML: <ComboBox Name="ComboBoxLieferant" ItemsSource="{Binding}" DisplayMemberPath="LFR_NAME" IsSynchronizedWithCurrentItem="True" SelectionChanged="ComboBoxLieferant_SelectionChanged" />
and <DataGrid Name="dg1" ItemsSource="{Binding Path=FK_TBL_MATERIAL_TBL_LIEFERANTENSTAMM}" IsSynchronizedWithCurrentItem="True">
Is there a way to filter like this without "breaking" the binding?
Thanks for help!
I solved this problem by myself.
I created a filter class in which I create a BindingListCollectionView.
Then I can easily filter this view with the customfilter.

In focus row in Xceed datagrid doesn't get updated

I have a Xceed Datagrid whose ItemsSource is CollectionViewSource defined in XAML. Whenever grid is updated, only the row which is in focus doesn't show updated values (revert back to original values) but all of other rows are updated. If I directly bound the grid to a Collection in ViewModel then everything works fine. The problem is only when, CollectionViewSource comes into picture. Any help is appreciated.
Can you try using the DataGridCollectionViewSource instead of a CollectionViewSource. By using this, you will reap the benefits of the DataGrid such as built in filtering, sorting, grouping, etc. An example from their documentation:
<Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
Source="{Binding Source={x:Static Application.Current},
Path=Orders}"/>
</Grid.Resources>
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_orders}}"/>
</Grid>
I got solution...
grid.CurrentItem = null

ComponentOne FlexGrid is empty

I just started using ComponentOne. Among other things, I need DataGrid with filtering capability for my WPF Caliburn.Micro application. So I tried to replace my common DataGrid with C1DataGrid, then C1FlexGrid, but in both cases the DataGrid was empty.
Here is my code:
<c1:C1FlexGrid x:Name="EnrollmentFiles" Grid.Row="1"
AutoGenerateColumns="False"
BaseControls:DataGridExtension.Columns="{Binding EnrollmentFileColumns}"
IsReadOnly="True"
SelectedItem="{Binding Path=SelectedEnrollmentFile, Mode=TwoWay}">
</c1:C1FlexGrid>
Could you please tell me what I am missing? Also, should I use C1DataGrid or FlexGrid?
Thanks
It's possible that by having SelectedItem bound the convention isn't working. If you're using the convention and want ItemsSource bound to EnrollmentFiles and you want to use SelectedItem, then create a property called SelectedEnrollmentFile and CM will do the SelectedItem binding too.

How to set a filter for a DataGrid ItemSource via MVVM

I have a DataGrid bound to a CollectionViewSource in XAML.
<Window.Resources>
<local:MainWindowViewModel x:Key="ViewModel"/>
<CollectionViewSource x:Key="cvsEntries"
Source="{Binding LogEntriesStore,
Source={StaticResource ViewModel}}"/>
</Window.Resources>
LogEntriesStore is an ObservableCollection (LogEntry is a DTO that's not important in this discussion)
The DataGrid is declared as:
<DataGrid AutoGenerateColumns="False"
Margin="0"
Name="dataGrid1"
ItemsSource="{Binding Source={StaticResource cvsEntries}}"
IsReadOnly="True">
Now I have context menus on various cells in this DataGrid, to kick off a request for filtering. Right click on a cell, and pick filter to filter all the rows, and show only this particular value.
The MVVM gets the request to filter, but the now the tricky bit. How do I set the filter on the CollectionViewSource?
(as an aside -- this would have been a walk in the park with a Silverlight PagedCollectionView but that doesn't seem to be available in WPF, is that right?)
Very simple. You just need to move the collection view inside the view model:
In MainWindowViewModel define a property of type ICollectionView:
public ICollectionView LogEntriesStoreView { get; private set; }
Right after you have initialized the LogEntriesStore property, you need to initialize the LogEntriesStoreView property with the following code:
LogEntriesStoreView = CollectionViewSource.GetDefaultView(LogEntriesStore);
Then you need to remove the CollectionViewSource from XAML and modify the ItemsSource binding to point to the newly created collection view property:
<DataGrid AutoGenerateColumns="False"
Margin="0"
Name="dataGrid1"
ItemsSource="{Binding LogEntriesStoreView, Source={StaticResource ViewModel}}"
IsReadOnly="True">
That's it. Now you have the access to the collection view inside your view model, where you can modify the filter.
There are several solutions to your problem, but in my opinion, the best solutions are the ones which uses only styles with the standard WPF DataGrid control without inventing a new inherited DataGird type or depending on another third-party control. The followings are the best solutions I found:
Option 1: which I personally use: Automatic WPF Toolkit DataGrid Filtering
Option 2: Auto-filter for Microsoft WPF DataGrid

Silverlight: Datagrid like grouping in ItemsControl

Is it possible to group items in a ItemsControl or Listbox in Silverlight? These controls are bound to a DomainDataSource.
Or are there any 3rd party controls that do this?
UPDATE:
This is the sort of UI I am trying to create.
You can do this by using nested ItemsControls bound to a PagedCollectionView.
Say I have a datasource - MyItems - with fields: Category, Section and Option. I can create a PagedCollectionView from an IEnumerable(of MyItems) and tell it which fields to group by.
Dim original As IEnumerable(Of MyItems) = GetMyItems()
Dim pcv = New PagedCollectionView(original)
pcv.GroupDescriptions.Add(New PropertyGroupDescription("Category"))
pcv.GroupDescriptions.Add(New PropertyGroupDescription("Section"))
Then I bind my first ItemsControl to the PagedCollectionView
hisMyItems.ItemsSource = pcv.Groups
The PCV creates a nested hierachy like:
-Name
-Items
where Name is the value in the grouped field and Items contains the rows/objects in that grouping. I guess you could also create the PCV in xaml if you prefer.
The xaml would look something like:
<controls:HeaderedItemsControl x:Name="hisMyItems" Header="{Binding Name}" ItemsSource="{Binding Items}" >
<controls:HeaderedItemsControl.ItemTemplate>
<DataTemplate>
<controls:HeaderedItemsControl Header="{Binding Name}" ItemsSource="{Binding Items}" ItemsPanel="{StaticResource ItemsPanelTemplate1}" >
<controls:HeaderedItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Option}" />
</DataTemplate>
</controls:HeaderedItemsControl.ItemTemplate>
</controls:HeaderedItemsControl>
</DataTemplate>
</controls:HeaderedItemsControl.ItemTemplate>
</controls:HeaderedItemsControl>
I hope that makes sense. I have tried to simplify things from my actual app but I could have made some mistakes in copying it over. Obviously you could use normal ItemsControls or other controls too and customize with templates etc.
The DataGrid control supports grouping.
Tim Heuer has a good blog on grouping with a datagrid.
link text
Perhaps the control you are really looking for is the Accordian Control from the Toolkit.
See sample of Accordian behaviour here.
Note that the actual appearance is as style-able as any other control. The basic function is to group categories of items that would otherwise be a straight-forward List.

Resources