Silverlight - use combobox to select datagrid item - silverlight

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;
}

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);
}

Binding Observable collection list to dynamically created ComboBox in Silverlight

I have a requirement where I need to bind a list of observable collections to the item source of dynamically created ComboBoxes.
The problem is we bind through xaml conventionally in ItemsSource property but now the control rows in the grid are being added dynamically so each ComboBox in a row reference to the same collection whereas I need to bind it to a separate collection in observable collection list each time a row in the grid is added.
This what I have tried so far, any guidance would be appreciated. Thanks.
public virtual List<ObservableCollection<ComboBoxEntity>> ListRewardRule { get; set; }
Xaml :
<itimControls:ComboBox Name="cboReward"
IsMandatory="True"
itimComponents:ComponentManager.ComponentId="TXT_GROUP_RULE"
MaxWidth="400"
MinWidth="150"
ItemsSource="{Binding ListRewardRule, ElementName=RDefinitionScreen}"
DisplayMemberPath="Name"
SelectedValuePath="Code"
Loaded="cboReward_Loaded"
SelectedValue="{Binding RewardRuleId, Mode=TwoWay}"
SelectionChanged="cboReward_SelectionChanged">
</itimControls:ComboBox>
.CS :
private void cboReward_Loaded(object sender, RoutedEventArgs e)
{
Itim.Framework.Silverlight.UI.Controls.ComboBox cboReward = ((Itim.Framework.Silverlight.UI.Controls.ComboBox)sender);
int row = (int)cboReward.GetValue(Grid.RowProperty);
if (Model.ListRewardRule.Count > 0)
{
var rewardGroups = Model.RewardGroupAndTier.RewardGroups;
if(rewardGroups.Count > 1)
{
cboReward.ItemsSource = Model.ListRewardRule[row];
}
}
}
The way I understand this is, you have a “grid” (I suppose you mean a DataGrid) and each row in the grid has, among other things, a set of combo boxes.
What I’d do is bind that grid to an ObservableCollection of a custom class, call it CustomRowClass. CustomRowClass should have an ObservableCollection that will be bound to the combo boxes.
The magic is to define a DataTemplate for CustomRowClass. Once you set up the XAML this way, all you need to do is create an instance of CustomRowClass, and then add it to the ItemsSource of the grid.

Dynamically fill the ComboBox of an DataGridComboBoxColumn (WPF, DataGrid)

in my WPF application, I have a DataGrid, which is bound to an ObservableCollection.
<DataGrid x:Name="DataGridTeilnehmer" HorizontalAlignment="Left" VerticalAlignment="Top" CellEditEnding="DataGridTeilnehmer_CellEditEnding" AutoGenerateColumns="False" SelectionMode="Single">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Teilnehmer" CellEditingTemplate="{StaticResource TeilnehmerEditTemplate}" CellTemplate="{StaticResource TeilnehmerCellTemplate}" />
<DataGridComboBoxColumn Header="Pass" />
...
The DataGridComboBoxColumn shall be filled with individual values for each row. The values depend on the entry of the first column. So, I would like to set the data in the CellEditEnding event like this:
private void DataGridTeilnehmer_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (!commiting)
{
commiting = true;
DataGridTeilnehmer.CommitEdit(DataGridEditingUnit.Row, false);
commiting = false;
// check, whether it is the first column that has been edited
if (...)
// get the list<string> for the combobox depending on the edited content
// get the combobox of the current row and bind the calculated list<string> to it
}
}
}
How can I do this?
EDIT: An example of what I am trying to achieve.
I have list of customers, which have individual tickets each. When the customer has been chosen in the first column, I want to load the ticket-list this customer has and load it into the next column - the combobox column.
Thanks in advance,
Frank
If you bound your datagrid to an ObservableCollection and your object implements INotifyPropertyChanged you can achieve what you need without using cell editending event.
In your model just check the value of your first column then set others columns values:
private string _firstColumn;
public string FirstColumn
{
get { return _firstColumn; }
set {
_firstColumn = value;
if(value == ...)
//set other properties
...
//notify the change
OnPropertyChanged("FirstColumn"); }
}
when your datagridrow lost focus all the new values will be notified to the datagrid

Programatically bringing a Datagrid row into view in WPF, MVVM

I would like to bring a row of my data grid into view programatically. I have a more than 100 rows. When I create a row(which I am doing by adding an item to a observable collection) I would like that new row to be selected and bring that into view. I was able to select the new row in my code but could not do the scrolling. More over I want the first cell of the row to be in edit mode so that the user can input text. I am following MVVM pattern for the application and would like to keep zero code in my views. How Can I achieve this?
Any help or suggestion will be appreciated....
Update:
This what I did in my XAML
<telerik:RadGridView ItemsSource="{Binding AllPartClasses}"
SelectedItem="{Binding SelectedPartClassViewModel, Mode=TwoWay}"
SelectionMode="Single" IsSynchronizedWithCurrentItem="True">
in my view model I did this
void AddNewPartClassExecute()
{
PartClass newPartClass = new PartClass();
PartClassViewModel tempPartClass = new PartClassViewModel(newPartClass);
tempPartClass.IsInValid = true;
AllPartClasses.Add(tempPartClass);
SelectedPartClassViewModel = tempPartClass;
Global.DbContext.PartClasses.AddObject(newPartClass);
//OnPropertyChanged("AllPartClasses");
}
public PartClassViewModel SelectedPartClassViewModel
{
get
{
return _selectedPartClassViewModel;
}
set
{
_selectedPartClassViewModel = value;
OnPropertyChanged("SelectedPartClassViewModel");
}
}
It did not work for me.
For the regular WPF DataGrid you can use ScrollIntoView. In your view hookup the SelectionChanged event to the following in your view code-behind cs file.
private void OnSelectionChanged( object sender, SelectionChangedEventArgs e )
{
Selector selector = sender as Selector;
DataGrid dataGrid = selector as DataGrid;
if ( dataGrid != null && selector.SelectedItem != null && dataGrid.SelectedIndex >= 0 )
{
dataGrid.ScrollIntoView( selector.SelectedItem );
}
}
When following MVVM pattern you should not do a UI-specific stuff like scrolling from a code.
Solution would be simple - just bind DataGrid.SelectedItem to a property in ViewModel and when adding a new item in the items collection just update a property bound to SelectedItem so it would reference to just added item and data grid should select an appropriate row automatically.
<DataGrid
ItemsSource="{Binding UnderyingItemsCollection}"
SelectedItem="{Binding RecentlyAddedItem, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True">

wpf datagrids binding and SelectionMode Single

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.

Resources