How to sort the [include] entitycollection in Ria Silverlight - silverlight

I have datagrid with another datagrid in the rowdetails and I am not able to sort the details view
I have tried the following but no success :(
The main datagrid is populated in the following manner:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
NamskeidinDomConTxt = new Namskeidin_DomainContext();
this.NamskeidinDomConTxt.Load(this.NamskeidinDomConTxt.GetNamskeidQuery(), LoadBehavior.RefreshCurrent, loadOperation =>
{
PagedCollectionView pcView = new PagedCollectionView(loadOperation.Entities);
pcView.SortDescriptions.Add(new SortDescription("Heiti", ListSortDirection.Ascending));
namskeidDataGrid.ItemsSource = pcView;
}, null);
}
The datagrid in the detailsrow of the main datagrid is populated in the following manner:
First I catch the following event and get the details datagrid.
private void namskeidsHlutarDataGrid_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
verkefniDataGrid = (e.DetailsElement as FrameworkElement).FindName("VerkefniDataGrid") as DataGrid;
Verkefni_DomConTxt = new Verkefni_DomainContext();
}
and then the this event fiers so I can fill the details datagrid when I have got the id:
private void namskeidsHlutarDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
var item = dataGrid.SelectedItem;
if (item != null)
{
nHlutaId = ((Entity)item).GetIdentity().ToString();
Verkefni_DomConTxt.Load(Verkefni_DomConTxt.GetVerkefniQuery().Where(v => v.NamskeidsHluta_ID == nHlutaId),
LoadBehavior.RefreshCurrent, loadOperation =>
{
verkefniDataGrid.ItemsSource = loadOperation.Entities;
}, null);
}
}
private void GridName_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
var dataGrid = (e.DetailsElement as FrameworkElement).FindName("detailsDataGrid") as DataGrid;
PagedCollectionView pcView = new PagedCollectionView(dataGrid.ItemsSource as IEnumerable);
pcView.GroupDescriptions.Clear();
pcView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
pcView.Refresh();
}
There are actualy three datagrids details/details
Can anyone help me with this?

You're creating a new PagedCollectionView but your DataGrid's ItemsSource is still bound to the plain IEnumerable. You'll need to bind the ItemsSource to your PagedCollectionView.
Updated: So based on your updated code you should just load the child grid the same way you load the parent grid. So instead of:
Verkefni_DomConTxt.Load(Verkefni_DomConTxt.GetVerkefniQuery().Where(v => v.NamskeidsHluta_ID == nHlutaId), LoadBehavior.RefreshCurrent,
loadOperation => { verkefniDataGrid.ItemsSource = loadOperation.Entities;}, null);
You could just create your data view here and set the items source to point to it:
Verkefni_DomConTxt.Load(Verkefni_DomConTxt.GetVerkefniQuery().Where(v => v.NamskeidsHluta_ID == nHlutaId), LoadBehavior.RefreshCurrent,
loadOperation => {
PagedCollectionView pcView = new PagedCollectionView(loadOperation.Entities);
pcView.GroupDescriptions.Clear();
pcView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
verkefniDataGrid.ItemsSource = pcView;
}, null);
And then get rid of your other event that tries to create the view.

Related

WPF DataGrid pressing enter on first cell it is adding new row I want it to add new row on las cell pressing enter

WPF Datagrid it is adding new row while pressing enter on first cell I want it to add new row once I press last cell of Datagrid.
Please check demo app is here:
WPFDemo
Thank you,
Jitendra Jadav
The DataGrid also adds a new row even when you don't even press ENTER. If you don't want this behaviour, you would probably be better of setting the CanUserAddRows property to false and add the items yourself to the source collection. Something like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
dataGrid.CanUserAddRows = false;
//add blank row
var itemsSource = dataGrid.ItemsSource as ObservableCollection<ItemModel>;
if (itemsSource != null)
itemsSource.Add(new ItemModel());
Loaded += MainWindow_Loaded;
dataGrid.PreviewKeyDown += DataGrid_PreviewKeyDown;
}
private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if(e.Key == Key.Enter)
{
if (Keyboard.FocusedElement is UIElement elementWithFocus)
{
if (dataGrid.Columns.Count - 1 == dataGrid.CurrentCell.Column.DisplayIndex)
{
var itemsSource = dataGrid.ItemsSource as ObservableCollection<ItemModel>;
if (itemsSource != null)
{
var newItem = new ItemModel();
itemsSource.Add(newItem);
dataGrid.SelectedItem = newItem;
Dispatcher.BeginInvoke(new Action(()=>
{
DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromItem(newItem) as DataGridRow;
DataGridCell cell = Helper.GetCell(dataGrid, row, 0);
if (cell != null)
dataGrid.CurrentCell = new DataGridCellInfo(cell);
}), DispatcherPriority.Background);
}
}
else
{
elementWithFocus.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
e.Handled = true;
}
}
}
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Helper.SelectRowByIndex(dataGrid, 0);
}
}

use a combobox selection for linq query

I have a combobox that gets populated from a database table. When the combobox is diplayed in the window it has the StationName, but it also has a "hidden" value for a StationId. Here is how I get the combobox to display the choices:
StationBox.ItemsSource = dc.WasteTrackerStations;
How can I get to that StationId property to use that in a seperate query to populate a datagrid? This is the code for my SelectionChanged event:
private void StationBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var miquery = from mi in dc.WasteTrackerDBs
where mi.StationId == [this value needs to be StationId from combobox selection]
select new
{
mi.MenuItem,
mi.LeftOver,
mi.Par,
mi.UoM,
mi.StationId
};
EWDataGrid.ItemsSource = miquery;
}
ComboBox has SelectedItem property. It will be an element of dc.WasteTrackerStations collection (or null). Cast it to concrete type and all properties will be accessible:
private void StationBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = StationBox.SelectedItem as WasteTrackerStation;
if (item == null) return;
var selectedStationId = item.StationId;
var miquery = from mi in dc.WasteTrackerDBs
where mi.StationId == selectedStationId
select new
{
mi.MenuItem,
mi.LeftOver,
mi.Par,
mi.UoM,
mi.StationId
};
EWDataGrid.ItemsSource = miquery;
}

WPF DataGrid : TemplateColumn with UserControl and TextBlock

Im a bit stuck here.. been searching for two days and found no solution.
What i would like to achieve is the behavior of DataGridComboBoxColumn .
I need its DisplayMemberPath, SelectedValuePath and SelectedValueBinding properties..
Im having my UserControl similar to ComboBox in the CellEditingTemplate
and TextBlock in CellTemplate.
Im doing all these in code, since these columns may not exist necessarily..
This is where i define the TemplateColumn :
DataGridTemplateColumn tcol = new DataGridTemplateColumn();
tcol.Header = "accCust";
FrameworkElementFactory texttablF = new FrameworkElementFactory(typeof(TextTableBox));
texttablF.SetValue(TextTableBox.TableSourceProperty, accTable.DefaultView);
FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
texttablF.SetBinding(TextBlock.TextProperty, new Binding("Account"));
tcol.CellTemplate = new DataTemplate(typeof(DataGridCell)) { VisualTree = tb };
tcol.CellEditingTemplate = new DataTemplate(typeof(DataGridCell)) { VisualTree = texttablF };
I have two issues :
TextBlock shows the ID present in the DataGrid's Table, I want it to show the value specified in the DisplayMemberPath, which i have no idea how to implement.
The DependencyProperty TableSource isnt working when done via FrameworkElement.setValue.. It works when it is done in the normal way,
ie
TextTableBox ttb = new TextTableBox();
ttb.TableSource = src_table.DefaultView;
I hope its clear to you what my problem is.. All i really want is to replace the ComboBox in DataGridComboColumn with my UserControl..
Thanks in advance :)
Im sorry if it is a poor question.. Im new to WPF and doing my HighSchools..
Because i wanted the Properties of ComboBox, i had to inherit from DataGridComboBoxColumn.
Heres how the code looks like :
public class DataGridTCBColumn : DataGridComboBoxColumn
{
private TableComboBox comboBox;
public DataGridTCBColumn(bool Editable)
{
comboBox = new TableComboBox() { IsEditable = Editable };
}
// Requires extra field..
public string SelectedValuePathX
{
get
{
return (string)this.GetValue(SelectedValuePathXProperty);
}
set
{
this.SetValue(SelectedValuePathXProperty, value);
}
}
static FrameworkPropertyMetadata SelectedValuePathXPropertyMeta = new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(SelectedValuePathXPropertyChanged));
public static readonly DependencyProperty SelectedValuePathXProperty =
DependencyProperty.Register("SelectedValueX", typeof(string), typeof(TableComboBox), SelectedValuePathXPropertyMeta);
private static void SelectedValuePathXPropertyChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
{}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (e.Property == DataGridTCBColumn.ItemsSourceProperty)
{
comboBox.ItemsSource = ItemsSource;
}
else if (e.Property == DataGridTCBColumn.SelectedValuePathProperty)
{
comboBox.SelectedValuePath = SelectedValuePath;
}
else if (e.Property == DataGridTCBColumn.DisplayMemberPathProperty)
{
comboBox.DisplayMemberPath = DisplayMemberPath;
}
base.OnPropertyChanged(e);
}
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
return comboBox;
}
protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
{
DataGridCell cell = editingEventArgs.Source as DataGridCell;
if (cell != null && !string.IsNullOrEmpty(this.SelectedValuePathX))
{
//For Typed DataSet
object obj = ((DataRowView)editingElement.DataContext).Row[this.SelectedValuePathX];
comboBox.SelectedValue = obj;
}
comboBox.Focus();
return comboBox.SelectedItem;
}
protected override bool CommitCellEdit(FrameworkElement editingElement)
{
if (!string.IsNullOrEmpty(this.SelectedValuePathX) && comboBox.SelectedValue != null)
((DataRowView)editingElement.DataContext).Row[this.SelectedValuePathX] = comboBox.SelectedValue;
return true;
}
}
Had to make another dependency propertry SelectedValuePathX. Actually, it does the job of SelectedValueBinding. However that Binding never did work (tried goin through the source code of ComboBox (Microsoft Reference Source) but dint work out well either.
Hopes it would help somebody :)

How to reload datagrid in wpf

I have a WPF application where I want to select item from datagrid and pass to textbox. after that on add button selected gridrow must be remove. I have a stored procedure to remove from table. And at same time reload the table in same datagrid.
I tried this code
private void refresh()
{
datagrid1.items.refresh();
}
private void btnAdd_Click(object Sender, RoutedEventArg e)
{
refresh();
}
private void datagrid1_SelectionChange(object Sender, RoutedEventArg e)
{
var selectedrow = datagrid1.selectedItem as datarowview;
var id = selectedrow["Tagid"]; // Here I get error that object reference is not set is an instance of an object
string s = conver.tostring(id);
txttextbox1.text= s;
}
After click add button, I get the error
Object reference not set to an instance of an object
You are forcing your selected item as datarowView which it is not, cast to correct type
var selectedrow = datagrid1.selectedItem as DataRowView
SelectedItem is type of object that is bound to grid not row
Try doing this
private void datagrid1_SelectionChange(object Sender, RoutedEventArg e)
{
var selectedItem = datagrid1.selectedItem as MY_Custom_Object;
var id = selectedItem.Tagid;
string s = Convert.ToString(id);
txttextbox1.text= s;
}

Catch RowEdited event in DataGrid WPF

How to catch event when DataGrid's row was edited and get all values from it?
If I use RowEditEnding event, I can't get new values...
Thanks!
See the discussion here, and this solution:
private void OnRowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
if (e.EditAction == DataGridEditAction.Commit) {
ListCollectionView view = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource) as ListCollectionView;
if (view.IsAddingNew || view.IsEditingItem) {
this.Dispatcher.BeginInvoke(new DispatcherOperationCallback(param =>
{
// This callback will be called after the CollectionView
// has pushed the changes back to the DataGrid.ItemSource.
// Write code here to save the data to the database.
return null;
}), DispatcherPriority.Background, new object[] { null });
}
}
}

Resources