How to bind index of item in BindableLayout.ItemsSource - xaml

I want a collection of buttons that show their corresponding item's index in MyObservableCollection as Text, and execute a Command with the CommandParameter also being this index. How can I achieve this?
<StackLayout BindableLayout.ItemsSource="{Binding MyObservableCollection}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Button Text="{Binding [index of the item in MyObservableCollection]}"
Command="{Binding MyCommand}"
CommandParameter="{Binding [index of the item in MyObservableCollection]}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>

So lets do the "hacky" thing you mentioned in the comments in the right "un-hacky" way^^
I would build something along the following lines. First we make an IIndexable interface:
public interface IIndexable
{
int Index { get; set; }
}
We now make our own implementation of ObservableCollection<T> like this:
public class IndexableObservableCollection<T> : ObservableCollection<T> where T : IIndexable
{
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move:
for (int i = 0; i < e.NewItems.Count; i++)
if (e.NewItems[i] is IIndexable indexableItem)
indexableItem.Index = e.NewStartingIndex + i;
break;
}
base.OnCollectionChanged(e);
}
}
For now I've only done the most basic implementation in the switch here (granted in this case the switch can be replaced by an if statement, but this makes it easier for you to implement all the options), you'll have to look into the NotifyCollectionChangedEventArgs yourself and implement the cases accordingly.
After this just have classes you want to be able to show an index of implement the IIndexable interface and put them in an IndexableObservableCollection and this will automatically set their index when they're added. in xaml you can then just use {Binding Index} to bind to this automatically set index.
Hope this helps

Related

Why I get exception when setting ComboBox.SelectedIndex?

I am trying to learn about bindings and XAML. I have a very simple example, where I bind an array of strings to a combobox defined in XAML. I also want to set the selected index.
I am getting an exception:
Value does not fall within the expected range.
with the SelectedIndex property.
Here my XAML for a UWP application.
<StackPanel Background="{ThemeResource applicationPageBackgroundThemeBrush}">
<ComboBox Name="BrowserCombo" ItemsSource="{x:Bind ComboStrings}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
and the code behind
public sealed partial class MainPage : Page
{
private string[] comboStrings = { "One", "Two", "Three" };
public List<String> ComboStrings
{
get { return new List<string>(comboStrings); }
}
public MainPage()
{
this.InitializeComponent();
DataContext = this;
BrowserCombo.SelectedIndex = 1;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// BrowserCombo.SelectedIndex = 1;
}
}
I want to have it very simple, so no MVVM - I still need to learn this concept.
Remarks:
I can put SelectedIndex in the XAML file. Same problem.
If I put the SelectedIndex in the Page_Loaded event handler, it works fine.
In a classic desktop XAML (aka WPF) there will be no problem.
It seems to be that the item list will be populated differently between XAML-WinRt and XAML-WPF. What is the earliest point to access the SelectedIndex property?
You get this exception because your ItemsSource is still null when you try to set BrowserCombo.SelectedIndex = 1; in the page's constructor. You are using x:Bind - if you debug the generated MainPage.g.cs file and put some breakpoints there:
public void Loading(global::Windows.UI.Xaml.FrameworkElement src, object data)
{
this.Initialize();
}
public void Initialize()
{
if (!this.initialized)
{
this.Update();
}
}
public void Update()
{
this.Update_(this.dataRoot, NOT_PHASED);
this.initialized = true;
}
You will see that x:Bind is being resolved in Loading event - this explains why in constructor you still have null in ItemsSource.
The other thing is that with old Binding - it is resolved when you set DataContext = this;, but you are using x:Bind and in fact you don't need to set the DataContext - it doesn't change anything here. If you replace ItemsSource="{x:Bind ComboStrings}" with ItemsSource="{Binding ComboStrings}" then your code should work, otherwise you may remove the line DataContext = this;.
Another interesting thing is that the order of defined bindings in XAML, can also cause similar troubles - for example if you define your ComboBox like this:
<ComboBox Name="BrowserCombo" SelectedIndex="{x:Bind Index}" ItemsSource="{x:Bind ComboStrings}">
then you will also get exception - SelectedIndex is being resolved before the collection is set up. Opposite to the situation when it works fine:
<ComboBox Name="BrowserCombo" ItemsSource="{x:Bind ComboStrings}" SelectedIndex="{x:Bind Index}">

How to bind a ReactiveCommand to a control in a Xamarin.Forms ListView?

I am using ReactiveUI, Xamarin.Forms and XAML. I am trying to implement a simple scenario with a ListView where each row has a delete button. Here is the ListView XAML:
<ListView x:Name="playerListView" ItemsSource="{Binding Players}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="20, 5, 20, 5">
<Label Text="{Binding .}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" />
<Button x:Name="deleteButton" Text="Delete" Clicked="onDeleteClicked" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As you can see, the delete button has a Clicked handler registered. This works but it does not feel like the RxUI way. Here is the code behind:
private void onDeleteClicked(object sender, EventArgs e)
{
var button = (Button)sender;
this.ViewModel.RemovePlayer.Execute(button.BindingContext);
}
How can I replace this onDeleteClicked event handler with a declarative binding to my RemovePlayer command? I can't see a good way to do it because I chose to bind the ListView to a ReactiveList<string>, so if I try to do Command="{Binding RemovePlayer}" it fails because the cell is bound to a string.
For completeness here is my view model:
public class NewGameViewModel : ReactiveObject
{
public ReactiveList<string> Players { get; private set; }
public ReactiveCommand<Object> AddPlayer { get; private set; }
public ReactiveCommand<Object> RemovePlayer { get; private set; }
public ReactiveCommand<Object> StartGame { get; private set; }
public ReactiveCommand<Object> RandomizeOrder { get; private set; }
string newPlayerName;
public string NewPlayerName {
get { return newPlayerName; }
set { this.RaiseAndSetIfChanged(ref newPlayerName, value); }
}
public NewGameViewModel()
{
Players = new ReactiveList<string> ();
var canStart = this.Players.CountChanged.Select(count => count >= 3);
StartGame = canStart.ToCommand();
RandomizeOrder = canStart.ToCommand();
AddPlayer = this.WhenAnyValue(x => x.Players.Count, x => x.NewPlayerName,
(count, newPlayerName) => count < 7 && !string.IsNullOrWhiteSpace(newPlayerName) && !this.Players.Contains(newPlayerName))
.ToCommand();
RemovePlayer = ReactiveCommand.Create();
}
}
Because there is no relative binding support in Xamarin Forms at the moment (see this Xamarin Forms forums post for more info), you won't be able to bind a command to your Button within your ListViews DataTemplate. Any binding within that DataTemplate will have a BindingContext relative to the current item in the list - in your case, a simple string. If your ListView was bound to an object, let's say a Person, then your Button command binding would still fail with an error something along the lines of No Command RemovePlayer found on object Person
So implementing the Command in the view's code behind like you have done is one option. Another is using a C# DataTemplate (not a XAML one) and implementing the Command there - but both of those are kind of the same thing. Neither are a great solution if you like keeping stuff like that out of your views and only within your view models; but until relative binding support is introduced there aren't really any other options.
I ran into the exact same problem as you, but I was binding my ListView to a collection of objects. The class for my object was in a separate class library that ONLY has POCOs in it, and I did not like the idea of implementing a Command within one of my POCO's.
The tricky bit is that your "SelectedPlayer" isn't exposed in your ViewModel, so there's no way to do this the RxUI way. If it was, you can do something like:
RemovePlayer.Select(_ => SelectedPlayer).Subscribe(x => {
SelectedPlayer = null;
Players.Remove(x);
});
If your Player object was itself a ViewModel and "RemovePlayer" was on the Player itself, you can do this Tricky Trick:
Players.Changed.StartWith(null)
.Select(_ => Players
.Select(x => x.RemovePlayer.Select(__ => x))
.Merge())
.Switch()
.Subscribe(x => Players.Remove(x));
Here, we're saying, "Every time the Players list changes, I want to build a new Observable: Take the list of all the current players, and Select them into an Observable that fires when someone hits a RemovePlayer button - tell me when any of those new Observables fire"
My opinion on this is don't be a purist :)
Is not the best design model, but extend your object to handle a ICommand and bind to it.. it's the best solution for now imo.
If your objects are on the same assembly you can use partial's , if are different , you can create small viewmodel for your poco .

How to execute command from GridViewItem Tap event (XAML)

I am trying to follow the MVVM pattern in my Windows 8.1 store app (XAML).
I want to navigate to a new view when a GridViewItem is clicked / tapped in the UI. I wanted to do this without code behind events to promote testability (using MVVM Light).
In order to allow my UI to bind to a view model command I have been looking at the Microsoft Behaviors SDK (XAML) added via Add References -> Windows -> Extensions.
The following code in my view compiles but blows up when I tap the grid view item. Unfortunately it offers little help & just throws an unhandled win32 exception [3476].
Can somebody please help shed some light on the problem?
Namespaces used are;
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
<GridView x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Source={StaticResource GroupedSource}}"
IsSwipeEnabled="True"
IsTapEnabled="True">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Margin="0"
Height="230">
<StackPanel Orientation="Vertical"
HorizontalAlignment="Stretch">
<Image Source="{Binding Image}"
Stretch="UniformToFill"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
<StackPanel VerticalAlignment="Bottom"
Height="45"
Margin="0,-45,0,0">
<StackPanel.Background>
<SolidColorBrush Color="Black"
Opacity="0.75"
/>
</StackPanel.Background>
<TextBlock FontSize="16"
Margin="2"
Text="{Binding Name}"
TextWrapping="Wrap"
VerticalAlignment="Bottom"
/>
</StackPanel>
</StackPanel>
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding DataContext.SummaryCatagorySelectedCommand, ElementName=LayoutRoot}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
Edit. As requested, I've added the view model, containing specifically the command I want to fire from my behavior.
public class ViewModel : ViewModelBase
{
public RelayCommand<string> SummaryCatagorySelectedCommand { get; set; }
public ViewModel()
{
//
}
}
The simplest answer is to tell you that you should not use a command in this situation. First, the value of a command is that it both executes and communicates back the inability to execute to the interactive XAML control. For example, the button is disabled when the command is not available.
But since you are using the tapped event of a framework element, you are basically just using the control as if it is a simple method, and not a command at all. Your view model can have both commands and methods, of course. And behaviors can call both commands and methods.
To that end, the best scenario here for your solution is to change your approach from calling a command in your view model. Your difficulties are 1. the command is out of scope of the data template and 2. the command parameter is passed inside an out of scope threading context.
Here's what I would suggest to make your life easier and your app simpler.
Do not attach to the tapped event of the item. But instead attach to the itemclicked event of the gridview. This, of course, means you need to set IsItemClickEnabled to true on your gridview. Then don't call to a command, which is overhead you are not using, but instead call to a method.
This is what the method would look like in your viewmodel:
public async void ClickCommand(object sender, object parameter)
{
var arg = parameter as Windows.UI.Xaml.Controls.ItemClickEventArgs;
var item = arg.ClickedItem as Models.Item;
await new MessageDialog(item.Text).ShowAsync()
}
The name of the method does not matter (I even called it a Command to make the point), but the signature does. The behavior framework is looking for a method with zero parameters or with two object-type parameters. Conveniently, the two parameter version gets the event signature forwarded to it. In this case, that means you can use the ItemClickEventArgs which contains the clicked item. So simple.
Your gridview is simplified, too. Instead of trying to force the scope inside your data context you can simply reference the natural scope of the gridview to the outer viewmodel. It would look something like this:
<GridView Margin="0,140,0,0" Padding="120,0,0,0"
SelectionMode="None" ItemsSource="{Binding Items}"
IsItemClickEnabled="True">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ItemClick">
<Core:CallMethodAction MethodName="ClickCommand"
TargetObject="{Binding Mode=OneWay}" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
It's such a simpler solution, and doesn't violate anything in the MVVM pattern because it still pushes the logic out to your separated and testable viewmodel. It lets you effectively use behaviors as an event-to-command but actually using a simpler event-to-method pattern. Since the behavior doesn't pass the CanExecute value back to the control in the first place, this actually simplifies your viewmodel, too.
If, it turns out what you are wanting to do is reuse an existing command that is already leveraged elsewhere (which sounds like the 1% edge case) you can always create a shell method for this purpose that internally leverages the command for you.
As a warning, the RelayCommand that ships with Windows 8.1 does not properly implement ICommand as it does not first test CanExecute before Execute is invoked. In addition, the CanExecute logic in the typed RelayCommand does not pass the CommandParameter to the handler. None of this really matters, depending on who you are using commands in the first place. It matters to me though.
So, that's your answer. Change to GridView.ItemClicked and change from ViewModel.Command to ViewModel.Method. That makes your life easier, far easier, and makes your XAML more portable should you ever want to reuse your data template.
Best of luck!
When you tap on any item you change SelectedItem, I guess. You can Binding (Mode=TwoWay) SelectedItem and in Set() of property raise needed action.
Or you can use something like this and use as dependency property of your GridView.
public class GridViewItemClickCommand
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand),
typeof(GridViewItemClickCommand), new PropertyMetadata
(null, CommandPropertyChanged));
public static void SetCommand(DependencyObject attached, ICommand value)
{
attached.SetValue(CommandProperty, value);
}
public static ICommand GetCommand(DependencyObject attached)
{
return (ICommand)attached.GetValue(CommandProperty);
}
private static void CommandPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
// Attach click handler
(d as GridView).ItemClick += gridView_ItemClick;
}
private static void gridView_ItemClick(object sender,
ItemClickEventArgs e)
{
// Get GridView
var gridView = (sender as GridView);
// Get command
ICommand command = GetCommand(gridView);
// Execute command
command.Execute(e.ClickedItem);
}
}
If you have any problems, please ask :)
I had the same issued but I solved it in another way. I don't put the behavior insie the datatemplate, I do it in the GridView :
<GridView x:Uid="Flow"
x:Name="PlacesGridView"
Grid.Column="1" Grid.Row="2"
ItemTemplate="{StaticResource YourDataTemplate}"
ItemsSource="{Binding YourSource}" >
<Interactivity:Interaction.Behaviors>
<Behaviors:GoToDestinationOnSelected/>
</Interactivity:Interaction.Behaviors>
</GridView>
This is how GoToDestinationOnSelected looks like:
public class GoToDestinationOnSelected : DependencyObject, IBehavior
{
.....
void GoToDestinationOnGridViewItemSelected_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
object obj = (sender as ListViewBase).SelectedItem;
if (obj == null)
return;
if (obj is YourClass)
{
App.RootFrame.Navigate(typeof(CountryPlacesPage));
return;
((AssociatedObject) as ListViewBase).SelectedIndex = -1;
}
public DependencyObject AssociatedObject
{
get;
private set;
}
public void Attach(DependencyObject associatedObject)
{
AssociatedObject = associatedObject;
(associatedObject as ListViewBase).SelectionChanged += GoToDestinationOnGridViewItemSelected_SelectionChanged;
}
public void Detach()
{
(AssociatedObject as ListViewBase).SelectionChanged -= GoToDestinationOnGridViewItemSelected_SelectionChanged;
}
~GoToDestinationOnSelected()
{
}
In UWP(Window 10 and newer) Mobile App, apply the below code snippet
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ItemClick">
<Core:EventTriggerBehavior.Actions>
<Core:`enter code here`InvokeCommandAction Command="{Binding itemclick}"/>
</Core:EventTriggerBehavior.Actions>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>

Command parameter in EventTrigger

I'm working on WinRT with MvmmCross v3 framework and Windows.UI.Interactivity.
I want a TextBox with an EventTrigger on the event TextChanged which launch a Command. And also, I want in CommandParameter the text of the textBox.
So I have this code
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding UpdateText}" CommandParameter="{Binding Text}"/>
</i:EventTrigger>
public ICommand UpdateText
{
get
{
return new MvxCommand<object>((textSearch) =>
{
// code...
});
}
}
But my textSearch parameter equals to "{Windows.UI.Xaml.Controls.TextChangedEventArgs}" with all of these properties NULL.
I Tried also to declare explicitly my ElementName in the binding like
CommandParameter="{Binding Path=Text, ElementName=tes}
But it failed too.
Thanks
Do you really need to handle TextChanged event? You could be notified of the changes by just binding to the Text property:
<TextBox Text="{Binding TextValue, Mode=TwoWay}" />
And then in the view model:
private string _textValue;
public string TextValue
{
get
{
return _textValue;
}
set
{
if (_textValue == value)
return;
_textValue = value;
OnTextChanged(value); // react to the changed value
}
}
EDIT:
There are two things you need to be aware of, if you want to get to the Text value from inside your Command:
First, you need to fix the CommandParameter binding. By using {Binding Text} you are actually trying to bind to a property in your view model, i.e. you would first need to bind the TextBox.Text property to the same view model property. As you've said in the comment, that's no good for you because you need the info on every change and not only on lost focus, so the value you get is not up to date enough.
The right approach would therefore be your second attempt, i.e. binding directly to the TextBox using the ElementName syntax. Unfortunately triggers are not a part of the visual tree therefore they don't get access to the XAML name scope (you can read more about it in this blog post). You can work around that by using NameScopeBinding from MVVMHelpers.Metro package:
<Behaviors:NameScopeBinding x:Key="MyTextBox"
Source="{Binding ElementName=MyTextBox}" />
Now you can make the ElementName binding work:
<i:InvokeCommandAction Command="{Binding UpdateText}"
CommandParameter="{Binding Source.Text, Source={StaticResource MyTextBox}}"/>
You still have the second problem. The Text value that you are binding to only updates on lost focus so you don't get the right value when handling TextChanged event. The solution is to bind to the TextBox itself:
<i:InvokeCommandAction Command="{Binding UpdateText}"
CommandParameter="{Binding Source, Source={StaticResource MyTextBox}}"/>
And then inside the command get the Text property directly from the TextBox:
private void OnUpdateText(object parameter)
{
var value = ((TextBox) parameter).Text;
// process the Text value as you need to.
}
EDIT 2:
To make the above code work with the view model being in a PCL, there a couple of approaches you could take.
The simplest hack would be to use reflection. Since it is available in PCL you could get to the Text property and read its value:
private void OnUpdateText(object parameter)
{
var textProperty = textSearch.GetType().GetProperty("Text");
var value = textProperty.GetValue(parameter, null) as string;
// process the Text value as you need to.
}
A cleaner solution would be to put the WinRT specific code into a separate assembly abstracted via an interface. You would first create an interface in the PCL library:
public interface IUiService
{
string GetTextBoxText(object textBox);
}
And modify view model to accept this interface in the constructor:
public ViewModel(IUiService uiService)
{
_uiService = uiService;
}
In the command handler you would than use the method in the interface:
private void OnUpdateText(object parameter)
{
var value = _uiService.GetTextBoxText(parameter);
// process the Text value as you need to.
}
You would implement that interface in a WinRT library:
public class UiService : IUiService
{
public string GetTextBoxText(object textBox)
{
var typedTextBox = textBox as TextBox;
return typedTextBox.text;
}
}
In the application you reference this library and pass the implementation to view model:
var viewModel = new ViewModel(new UiService);
My favorite approach is different: I'd create a Behavior exposing a Text property automatically updated every time TextChanged event is triggered:
public class TextChangedBehavior : Behavior<TextBox>
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(TextChangedBehavior),
new PropertyMetadata(null));
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.TextChanged += OnTextChanged;
Text = AssociatedObject.Text;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.TextChanged -= OnTextChanged;
}
private void OnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
{
Text = AssociatedObject.Text;
}
}
Now I could bind a TextValue property to this behavior and react to its change in the property setter as already suggested at the very beginning of this long answer:
<TextBox>
<i:Interaction.Behaviors>
<b:TextChangedBehavior Text="{Binding TextValue, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</TextBox>

Problems with SelectedValue, SelectedIndex while data binding to a ComboBox c++/cx XAML Metro app

How can I use the value of the ComboBox's selected element in the following code?
C++:
namespace testtesttest
{
[Windows::UI::Xaml::Data::Bindable]
public ref class Wrapper sealed : Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
Wrapper()
{
// the index of the selected element of the combobox when the application starts
m_selectedElement = 2;
m_myStringArray = ref new Platform::Collections::Vector<int>(3);
// 1, 2, and 4 in the combobox list
m_myStringArray->SetAt(0,1);
m_myStringArray->SetAt(1,2);
m_myStringArray->SetAt(2,4);
}
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
property Windows::Foundation::Collections::IVector<int>^ MyStringArray
{
Windows::Foundation::Collections::IVector<int>^ get() { return m_myStringArray; }
}
property int SelectedElement
{
int get() { return m_selectedElement; }
void set(int value) { m_selectedElement = value; RaisePropertyChanged("SelectedElement"); }
}
protected:
void RaisePropertyChanged(Platform::String^ propertyName)
{
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(propertyName));
}
private:
Platform::Collections::Vector<int>^ m_myStringArray;
int m_selectedElement;
};
}
XAML:
<TextBlock HorizontalAlignment="Left"
Height="73" Margin="50,436,0,0"
TextWrapping="Wrap"
Text="{Binding Path=SelectedElement}"
VerticalAlignment="Top"
Width="200"/>
<ComboBox ItemsSource="{Binding Path=MyStringArray}"
SelectedIndex="{Binding Path=SelectedElement}"
HorizontalAlignment="Left"
Height="50" Margin="369,50,0,0"
VerticalAlignment="Top" Width="286"/>
I tested other bindings and they worked. I am setting the DataContext right.
The m_selectedElement = 2 in the constructor sets the selected element in the combobox to the 3rd in the list. The get() method of the SelectedElement property gets called, but the set() method doesn't. I checked this by placing a breakpoint. What am I doing wrong?
Also, is it possible to bind a Platform::Array^ to a ComboBox?
I tried using Platform::Array < Platform::String ^>^ and also Platform::Array < int>^ and I couldn't get it work. STL containers also didn't work. What are the other possible containers that can bind to a combobox?
Change
SelectedIndex="{Binding Path=SelectedElement}"
to
SelectedIndex="{Binding Path=SelectedElement, Mode=TwoWay}"
You need a two-way binding if you want the UI to update your ViewModel.
You can only use WinRT components in bindings (ref classes/structs, enum classes). Using Platform::Collections::Vector is generally the right choice when it's used for binding, especially because it also implements IObservableVector. STL containers don't work because they cannot travel across the ABI.