- Home
- Forum
- Xamarin.Forms
- Retrieving SfComboBox SelectedIndices From Inside SfPopup DataTemplate
Retrieving SfComboBox SelectedIndices From Inside SfPopup DataTemplate
I have a page in my application that utilizes the SfPopup to manage a set of filters. The filters are attached to several different Syncfusion Controls (SfSegmentedControl, SfComboBox, SfCheckBox, etc.)
I'm finding it difficult to authenticate the values selected by a ComboBox inside the SfPopup's DataTemplate. See Attached GIF for a visual of what I have and am trying to achieve.
This is what I have currently in my code:
XAML -- In my <ContentPage.Resources>
<DataTemplate x:Name="StatementFilterTemplate" x:Key="StatementFilterTemplate">
<StackLayout>
<StackLayout
x:Name="warehouse_override_selection"
Orientation="Vertical">
<Label />
<combobox:SfComboBox
x:Name="warehouse_selection_drop"
Watermark="Select Warehouse"
DataSource="{Binding StatementWarehousesAvailable}"
DisplayMemberPath="WarehouseReference">
<combobox:SfComboBox.TokenSettings>
<combobox:TokenSettings
Style="{StaticResource StandardTokenStyle}"/>
</combobox:SfComboBox.TokenSettings>
<combobox:SfComboBox.ItemTemplate>
<DataTemplate>
// Item Content
</DataTemplate>
</combobox:SfComboBox.ItemTemplate>
</combobox:SfComboBox>
<StackLayout>
<StackLayout
x:Name="warehouse_override_selection"
Orientation="Vertical">
<Label />
<combobox:SfComboBox
x:Name="warehouse_selection_drop"
Watermark="Select Warehouse"
DataSource="{Binding StatementWarehousesAvailable}"
DisplayMemberPath="WarehouseReference">
<combobox:SfComboBox.TokenSettings>
<combobox:TokenSettings
Style="{StaticResource StandardTokenStyle}"/>
</combobox:SfComboBox.TokenSettings>
<combobox:SfComboBox.ItemTemplate>
<DataTemplate>
// Item Content
</DataTemplate>
</combobox:SfComboBox.ItemTemplate>
</combobox:SfComboBox>
</StackLayout>
</StackLayout>
</DataTemplate>
</StackLayout>
</DataTemplate>
XAML.CS -- In OnAppearing()
popupLayout.PopupView.AcceptCommand = new AcceptPopupCommand();
VIEWMODEL
public class AcceptPopupCommand : ICommand
{
private SfComboBox comboWarehouse;
private SfComboBox comboChain;
private SfComboBox comboLocation;
private List<int> SelectedWarehouses = new List<int>();
private List<int> SelectedChains = new List<int>();
private List<int> SelectedLocations = new List<int>();
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
var stack = (parameter as SfPopupLayout).PopupView.ContentTemplate.CreateContent();
var warehouseStack = (stack as StackLayout).FindByName<StackLayout>("warehouse_override_selection");
comboWarehouse = (warehouseStack as StackLayout).FindByName<SfComboBox>("warehouse_selection_drop");
Debug.WriteLine("Whs pop: " + comboWarehouse.SelectedIndices.ToJson());
if(comboWarehouse.SelectedIndices != null)
{
foreach(var obj in ((List<int>)comboWarehouse.SelectedIndices))
{
SelectedWarehouses.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedWarehouses, "WarehouseSelectedStatement");
}
comboChain = (warehouseStack as StackLayout).FindByName<SfComboBox>("chain_selection_drop");
Debug.WriteLine("Chn pop: " + comboChain.SelectedIndices.ToJson());
if (comboChain.SelectedIndices != null)
{
foreach (var obj in ((List<int>)comboChain.SelectedIndices))
{
SelectedChains.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedChains, "ChainSelectedStatement");
}
comboLocation = (warehouseStack as StackLayout).FindByName<SfComboBox>("location_selection_drop");
Debug.WriteLine("Loc pop: " + comboLocation.SelectedIndices.ToJson());
if (comboLocation.SelectedIndices != null)
{
foreach (var obj in ((List<int>)comboLocation.SelectedIndices))
{
SelectedLocations.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedLocations, "LocationSelectedStatement");
}
}
}
{
private SfComboBox comboWarehouse;
private SfComboBox comboChain;
private SfComboBox comboLocation;
private List<int> SelectedWarehouses = new List<int>();
private List<int> SelectedChains = new List<int>();
private List<int> SelectedLocations = new List<int>();
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
var stack = (parameter as SfPopupLayout).PopupView.ContentTemplate.CreateContent();
var warehouseStack = (stack as StackLayout).FindByName<StackLayout>("warehouse_override_selection");
comboWarehouse = (warehouseStack as StackLayout).FindByName<SfComboBox>("warehouse_selection_drop");
Debug.WriteLine("Whs pop: " + comboWarehouse.SelectedIndices.ToJson());
if(comboWarehouse.SelectedIndices != null)
{
foreach(var obj in ((List<int>)comboWarehouse.SelectedIndices))
{
SelectedWarehouses.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedWarehouses, "WarehouseSelectedStatement");
}
comboChain = (warehouseStack as StackLayout).FindByName<SfComboBox>("chain_selection_drop");
Debug.WriteLine("Chn pop: " + comboChain.SelectedIndices.ToJson());
if (comboChain.SelectedIndices != null)
{
foreach (var obj in ((List<int>)comboChain.SelectedIndices))
{
SelectedChains.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedChains, "ChainSelectedStatement");
}
comboLocation = (warehouseStack as StackLayout).FindByName<SfComboBox>("location_selection_drop");
Debug.WriteLine("Loc pop: " + comboLocation.SelectedIndices.ToJson());
if (comboLocation.SelectedIndices != null)
{
foreach (var obj in ((List<int>)comboLocation.SelectedIndices))
{
SelectedLocations.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedLocations, "LocationSelectedStatement");
}
}
}
It seems no matther what I try, I can't access the SfComboBox's SelectedIndices from this ICommand interface. What am I missing?
Attachment: Popup_Filters_3ed39e03.zip
SIGN IN To post a reply.
7 Replies
KK
Karthikraja Kalaimani
Syncfusion Team
February 14, 2020 02:03 PM UTC
Hi Matthew,
Thank you for contacting Syncfusion support.
Based on the provided information we have checked your query “SelectedIndices cannot access from ICommand” and we found that you have created a new ContentTemplate of PopupView on Execute method of Command class. So it tends to create a new ComboBox. So only we cannot access SelectedIndices in the ICommand class. To overcome this issue make a public ComboBox property in ICommand class and initialized that ComboBox on BindigContext changed the event of Warehouse_selection_drop. For more details please refer to the below attached sample and code snippet.
Code Example,
Thank you for contacting Syncfusion support.
Based on the provided information we have checked your query “SelectedIndices cannot access from ICommand” and we found that you have created a new ContentTemplate of PopupView on Execute method of Command class. So it tends to create a new ComboBox. So only we cannot access SelectedIndices in the ICommand class. To overcome this issue make a public ComboBox property in ICommand class and initialized that ComboBox on BindigContext changed the event of Warehouse_selection_drop. For more details please refer to the below attached sample and code snippet.
Code Example,
|
[.CS]
public partial class MainPage : ContentPage {
public SfComboBox comboBox;
AcceptPopupCommand acceptCommand;
public MainPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
popup.Show();
}
protected override void OnAppearing()
{
base.OnAppearing();
acceptCommand = new AcceptPopupCommand();
popup.PopupView.AcceptCommand = acceptCommand;
}
private void Warehouse_selection_drop_BindingContextChanged(object sender, EventArgs e)
{
comboBox = (sender as SfComboBox);
acceptCommand.ComboBox = comboBox;
}
}
…
public class AcceptPopupCommand : ICommand
{
public SfComboBox ComboBox { get; set; }
private List<int> SelectedWarehouses = new List<int>();
private List<int> SelectedChains = new List<int>();
private List<int> SelectedLocations = new List<int>();
public event EventHandler CanExecuteChanged;
public AcceptPopupCommand()
{
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
if (ComboBox.SelectedIndices != null)
{
foreach (var obj in ((List<int>)ComboBox.SelectedIndices))
{
SelectedWarehouses.Add(obj);
}
MessagingCenter.Send<List<int>>(SelectedWarehouses, "WarehouseSelectedStatement");
}
}
}
[XAML]
<ContentPage.Resources>
<DataTemplate x:Key="StatementFilterTemplate">
<StackLayout>
<StackLayout
x:Name="warehouse_override_selection"
Orientation="Vertical">
<Label/>
<combobox:SfComboBox
BindingContextChanged="Warehouse_selection_drop_BindingContextChanged"
x:Name="warehouse_selection_drop"
MultiSelectMode="Token"
Watermark="Select Warehouse"
DataSource="{Binding MobileCollection}"
DisplayMemberPath="Mobile">
<combobox:SfComboBox.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Mobile}"></Label>
</DataTemplate>
</combobox:SfComboBox.ItemTemplate>
</combobox:SfComboBox>
</StackLayout>
</StackLayout>
</DataTemplate>
</ContentPage.Resources>
|
Sample link : https://www.syncfusion.com/downloads/support/directtrac/general/ze/Popup_Demo_2-440618339.zip
We hope this helps, please let us know if need further assistance from us.
Regards,
Karthik Raja
MB
Matthew Bailey
February 21, 2020 02:10 PM UTC
That was exactly what I needed.
Now in reverse, since the Popup isn't 'Opened' via an ICommand, but rather handled via an EventHandler through popupLayout.Opening or popupLayout.Opened --- How do I attached the SelectedIndicies that I passed out through the AcceptCommand back into the SfComboBox when I reopen the popup?
Currently, after I initiate the AcceptCommand - the popup closes and my list of selected indexes are passed along to my MessagingCenter control. But when I open the SfPopup again, my SfComboBox is empty.
Currently, after I initiate the AcceptCommand - the popup closes and my list of selected indexes are passed along to my MessagingCenter control. But when I open the SfPopup again, my SfComboBox is empty.
I need it to show the list of selected indexes that I previously selected. How do I achieve this?
SS
Sivaraman Sivagurunathan
Syncfusion Team
February 24, 2020 02:01 PM UTC
Hi Matthew,
Sorry for the inconvenience.
Currently we are validating the reported issue, we will update the details on 26th February 2020.
Regards,
Sivaraman
KK
Karthikraja Kalaimani
Syncfusion Team
February 26, 2020 01:11 PM UTC
Hi Matthew,
Thank you for your patience.
Your requirement can be achieved by storing the previously SelectedIndices of ComboBox in the closing event of SfPopupLayout and then assign that SelectedIndices to the ComboBox of MainPage class. For more details please refer to the below code snippet.
Your requirement can be achieved by storing the previously SelectedIndices of ComboBox in the closing event of SfPopupLayout and then assign that SelectedIndices to the ComboBox of MainPage class. For more details please refer to the below code snippet.
|
[XAML]
<ContentPage.Content> <sfPopup:SfPopupLayout x:Name="popup" Closing="Popup_Closing">
<sfPopup:SfPopupLayout.PopupView>
<sfPopup:PopupView ContentTemplate="{StaticResource StatementFilterTemplate}">
sfPopup:PopupView>
sfPopup:SfPopupLayout.PopupView>
<sfPopup:SfPopupLayout.Content>
<Button Text="clickTo Show popup" Clicked="Button_Clicked">Button>
sfPopup:SfPopupLayout.Content>
sfPopup:SfPopupLayout>
ContentPage.Content>
[.CS] public partial class MainPage : ContentPage {
public SfComboBox comboBox;
List<int> selectedIndices = new List<int>();
…. private void Warehouse_selection_drop_BindingContextChanged(object sender, EventArgs e)
{
comboBox = (sender as SfComboBox);
if (selectedIndices != null)
comboBox.SelectedIndices = selectedIndices;
acceptCommand.ComboBox = comboBox;
}
….. private void Popup_Closing(object sender, Syncfusion.XForms.Core.CancelEventArgs e) {
selectedIndices.Clear(); foreach (var obj in ((List<int>)acceptCommand.ComboBox.SelectedIndices))
{
selectedIndices.Add(obj);
}
}
} } |
About Closing Event in SfPopupLayout :
https://help.syncfusion.com/xamarin/popup/popup-events#closing-event
Regards,
Karthik Raja
MB
Matthew Bailey
April 27, 2020 01:34 PM UTC
Okay - so this method of using BindingContextChanged has been exactly what I was looking for but I have a follow up question.
1. I'm using a ViewModel for all my data binding, and it seems that I need to attach the bound data within the EventHandler otherwise the control doesn't display the current bound values - in my current application my codebehind doesn't handle the BindingContext = new ViewModel() assignment, so I don't have direct access to the VM in the code behind. So is there a way to build this in a ViewModel:
private void Warehouse_selection_drop_BindingContextChanged(object sender, EventArgs e)
1. I'm using a ViewModel for all my data binding, and it seems that I need to attach the bound data within the EventHandler otherwise the control doesn't display the current bound values - in my current application my codebehind doesn't handle the BindingContext = new ViewModel() assignment, so I don't have direct access to the VM in the code behind. So is there a way to build this in a ViewModel:
private void Warehouse_selection_drop_BindingContextChanged(object sender, EventArgs e)
{
comboBox = (sender as SfComboBox);
acceptCommand.ComboBox = comboBox;
}
KK
Karthikraja Kalaimani
Syncfusion Team
April 28, 2020 01:39 PM UTC
Hi Matthew,
Thanks for the update.
Thanks for the update.
Currently, we are validating your requirement. So, we will validate and update you further details on or before 30th April 2020. We appreciate your patience until then.
Regards,
Karthik Raja
KK
Karthikraja Kalaimani
Syncfusion Team
April 30, 2020 10:38 AM UTC
Hi Matthew,
We have checked your requirement and it not possible to move that process for getting the selectedIndices of ComboBox from BindingContextChanged event to ViewModel. Because ComboBox loaded as DataTemplate and the only way to get the selected Indices of ComboBox from DataTemplate via BindingContextChanged event. We have linked the below stack overflow discussions about getting a view from DataTemplate.
StackOverFlow link : https://stackoverflow.com/questions/49373982/access-views-inside-a-datatemplate-at-runtime-in-xamarin-forms
Regards,
Karthik Raja
We have checked your requirement and it not possible to move that process for getting the selectedIndices of ComboBox from BindingContextChanged event to ViewModel. Because ComboBox loaded as DataTemplate and the only way to get the selected Indices of ComboBox from DataTemplate via BindingContextChanged event. We have linked the below stack overflow discussions about getting a view from DataTemplate.
StackOverFlow link : https://stackoverflow.com/questions/49373982/access-views-inside-a-datatemplate-at-runtime-in-xamarin-forms
Regards,
Karthik Raja
SIGN IN To post a reply.
- 7 Replies
- 3 Participants
-
MB Matthew Bailey
- Feb 13, 2020 04:32 PM UTC
- Apr 30, 2020 10:38 AM UTC