wpf datagrids binding and SelectionMode Single - wpf

I had two datagrids in wpf: grid1 for all available plans and grid2 for the plans been selected. The two grids are separated by two buttons (>) and (<). Button (>) is to add the selected plan to the grid2 of associated plans and remove it from grid1. Button (<) is to remove selected item of grid2 and add it to grid1 (to remove from selected plans).
<DataGrid Name="grdAllPlans" SelectionMode="Single" ItemsSource="{Binding}">
<Button Click="linkClicked">
<Button Click="UnlinkClicked">
<DataGrid Name="grdSelectedPlans" SelectionMode="Single" ItemsSource="{Binding}">
I had two global variables that have the plans:
static List<PlanDTO> PlansAssociated = new List<PlanDTO>(); //contain plans selected
static List<PlanDTO> PlansAvailable = new List<PlanDTO>(); //contain all plans not selected
This is the method call to associate a plan (remove from grid1 and add it to grid2):
private void linkClicked(object sender, RoutedEventArgs e)
{
if (grdAllPlans.SelectedItem != null)
{
PlanDTO selectedPlan = (PlanDTO)grdAllPlans.SelectedItem;
PlansAvailable.Remove(selectedPlan); //remove from collection PlansAvailable
PlansAssociated.Add(selectedPlan); //add it to selected collection
//Update grid1
srcCollectionViewAvailable.Source = PlansAvailable;
grdPlansDisponibles.ItemsSource = srcCollectionViewAvailable.View;
//Update grid2
srcCollectionViewAssociated.Source = PlansAssociated;
grdPlansAsociés.ItemsSource = srcCollectionViewAssociated.View;
grdPlansAsociés.UnselectAll();
grdPlansDisponibles.UnselectAll();
}
}
The problem it is not working. The first time that I add a plan to the selected plan grid it do it well, but after that both grid do not get refresh.
Also SelectionMode="Single" do not work. I am been able to select multiple rows.

You need to use ObservableCollection, instead of List for those 2 global variables.
The problem is that the UI wasn't notified when list changes. Using ObservableCollection would notify the UI automatically.

Related

How to scroll to a given row when WPF DataGrid is loaded

I display a few thousand rows in a WPF DataGrid, but would like to automatically scroll to a specific row when it is loaded (and later also add a button to scroll to this specific row). Is it possible to achieve it via data binding or from a view model property?
Of course, I've already browsed the Internet, but could not find any corresponding property.. For exemple, SelectedCells only has a get accessor (but I don't think it would have scrolled whatsoever anyway). I don't think that the other properties, such as SelectedItem helps.
Thanks for any insights :-)
There are two options: scroll to a row without selecting it and scroll to a row and select it.
Scroll to row without selecting it
This solution works for any DataGrid.SelectionUnit value (cell or row based selection).
You set the row from a property in your view model, which binds to DataGrid.CurrentItem.
Scrolling must be handled by the DataGrid by handling the DataGrid.CurrentCellChanged event.
View model (must implement INotifyPropertyChanged)
object currentRow = this.DataSource[currentRowIndex];
this.CurrentRow = currentRow;
View.xaml
<DataGrid ItemsSource="{Binding DataSource}"
CurrentItem="{Binding CurrentRow}"
CurrentCellChanged="DataGrid_OnCurrentCellChanged" />
View.xaml.cs
private void DataGrid_OnCurrentCellChanged(object sender, EventArgs eventArgs)
{
var dataGrid = sender as DataGrid;
dataGrid.ScrollIntoView(dataGrid.CurrentItem);
}
Scroll to row by selecting it
This solution works only for DataGrid.SelectionUnit values DataGridSelectionUnit.FullRow or DataGridSelectionUnit.CellOrRowHeader (not cell-only based selection - cell-only solution must completely handle selection and scroll in view).
You set the selected row from a property in your view model, which binds to DataGrid.SelectedItem.
Scrolling must be handled by the DataGrid by handling the DataGrid.SelectionChanged event.
View model (must implement INotifyPropertyChanged)
object selectedRow = this.DataSource[currentRowIndex];
this.SelectedRow = selectedRow;
View.xaml
<DataGrid ItemsSource="{Binding DataSource}"
SelecetedItem="{Binding SelectedRow}"
SelectionChanged="DataGrid_OnCurrentCellChanged" />
View.xaml.cs
private void DataGrid_OnSelectionChanged(object sender, SelectionChangedEventArgs eventArgs)
{
var dataGrid = sender as DataGrid;
dataGrid.ScrollIntoView(dataGrid.SelectedItem);
}

Silverlight - use combobox to select datagrid item

I'm a bit new to WPF and .NET, so this may be a simple task:
I have textblocks that get their values from the selected item of a datagrid. I'm trying to bind a combobox to one column in that datagrid so the user sees all the values in that datagrid column. When selecting an item in the combobox, it should make that row the selected item in the datagrid as well.
Here is my DataGrid:
<sdk:DataGrid AutoGenerateColumns="True" Name="l1dGrid" IsReadOnly="True" ItemsSource="{Binding}" DataContext="{Binding Path=DataContext}" />
and here is where the Datagrid gets data loaded:
_PCContext.Load(_PCContext.GetLine1_DownstairsQuery());
l1dGrid.ItemsSource = _PCContext.Line1_Downstairs;
Now I just need a combobox to have the ability to change the selected item in the DataGrid.Thanks in advance for any assistance!!!
[EDIT - SOLVED]
Ok, so I ended up just querying the datagrid based on the selected item of the combobox and setting the datagrid selected item to the one that matched that query.Here is the code I used to do this:
private void stockPick_comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string selection = stockPick_comboBox.SelectedValue.ToString().Replace("Line1_Downstairs : ", "");
selectGridItem(selection);
}
private void selectGridItem(string selection)
{
var stock = (from i in _PCContext.Line1_Downstairs
where i.Stock == selection
select i).FirstOrDefault();
l1dGrid.SelectedItem = stock;
}

How to get ALL DataGrid's selected Item. (MOST up to date)

I am currently trying to get a collection of selected datagrid rows selected by the user (multi row selection on).
Each row is binded to a visual object which i want to show as selected"
So for the data grid I added this style:
<Style TargetType="DataGridRow">
<EventSetter Event="Selected" Handler="DataGrid_RowSelectionChanged" />
</Style>
So when the user selects a row I get an event fired.
However, when select a row and into the event. Selected item has not been updated yet and it still shows what I PREVIOUSLY selected. DataGrid.CurrentItem shows the row I just clicked and about to be selected, but since its multi select, I want to be able to get ALL the rows CURRENTLY selected and have my visual object "Highlighted"
Is there a way where I can get a MOST updated list of selected item from datagrid? Is there an event I can use that fires AFTER i selected my new row?
Thanks and Regards,
Kev
You want to use the DataGrid.SelectionChanged event. The SelectionChangedEventArgs will contain the items which were added or removed at the time of selection changing.
DataGrid dg = new DataGrid();
dg.SelectionChanged += new System.Windows.Controls.SelectionChangedEventHandler(OnSelectionChanged);
void OnSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
foreach (var addedItem in e.AddedItems)
{
//do stuff
}
foreach (var removedItem in e.RemovedItems)
{
//do stuff
}
}

How to get Listbox selected index?

I have a Listbox filled with Buttons. When the buttons is clicked then a new Page shows. But i wanna have the selected index of the listbox when i click on the button. But the listboxitem is never selected. Is there a way to get the index where the button lies by clicking the button. Thanks for help.
Example code
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Click="ViewDetail_Click" Content="{Binding Path=Area}"></Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The data context of the button will contain the source data item corresponding to the list item. You've not shown what your ItemsSource is for the list, so I can't show exactly what code you'd need. But something like this:
ObservableCollection<MyDataItem> items = new ObservableCollection<MyDataItem>();
...
myList.ItemsSource = items;
...
private void ViewDetail_Click(object sender, RoutedEventArgs e)
{
Button b = (Button) sender;
MyDataItem detailItem = (MyDataItem) b.DataContext;
int itemIndex = items.IndexOf(detailItem);
}
Of course, if the reason you're asking for the index in the first place is because you want to get hold of the corresponding data item, you don't actually need the index at all - the item's already right there in the data context.
By the way, I wouldn't use a ListBox here. The main thing ListBox brings to the party is selection, but by putting buttons in as the items, you're defeating that - as you've already discovered, the button is handling the mouse input before the list box has a chance to, meaning that you can't actually select the items. At which point, why have a ListBox? A base ItemsControl probably makes more sense. (Wrapped in a ScrollViewer if you need scrolling.)

How to stop automatic refresh of a WPF ListBox Databinded on a EntityFramework object

I have a Xaml Page with a Databinded ListBox and a detail grid to create or update selected element.
My Page.DataContext is binded on a ADO.NET Entity Data Model table ("Univers").
private void Page_Loaded(object sender, RoutedEventArgs e)
{
SEPDC = new Models.SEP();
universViewSource = new CollectionViewSource();
universViewSource.Source = SEPDC.Univers.Execute(System.Data.Objects.MergeOption.AppendOnly);
DataContext = universViewSource;
}
The Xaml code of the ListBox :
<ListBox DisplayMemberPath="Nom" ItemsSource="{Binding}" Name="universListBox" SelectedValuePath="IdUnivers"/>
When i select an element in the ListBox, the grid detail automatically display the information of the selected element
Here the "Nom" TextBox witch use TwoWay databinding :
<TextBox Name="nomTextBox" Text="{Binding Path=Nom, Mode=TwoWay}" />
When i modify the TextBox "Nom", the ListBox is automatically updated. Great ... But i haven't call the SaveChanges method of my SEPDC DataContext object ...
How can i stop the automatic refresh of my ListBox until i explicit call the SaveChanges method and if possible, without use the Binding UpdateSourceTrigger=Explicit option ?
Regards.
You can use two separate entity data context (SEPDC) objects. Your ListBox is bound to one and your detail grid to the other. When the SelectedValue changes in the ListBox, find the same entity in the detail grid's entity data context and set it. After saving changes from the detail grid's entity data context, refresh the one for the ListBox.
I use this technique but i have to recreate the ListBox SEPDC each time i refresh the ListBox.
List<Models.Univers> list;
using (Models.SEP dc = new Models.SEP())
list = dc.Univers.Execute(System.Data.Objects.MergeOption.AppendOnly).ToList();
universListBox.DataContext = list;
The Refresh method doesn't work.
Regards

Resources