AnsweredAssumed Answered

Having Troubles Displaying SimpleMarkerSymbols in a WPF ComboBox

Question asked by jennyc4i on May 3, 2016

I'm implementing a custom control with the goal to have a list of SimpleMarkerSymbols in a combobox and allow users to select an item and place that symbol on a map. All of this implemented in MVVM style with ReactiveUI powering the whole thing.

 

In my custom UserControl, all I have is the combobox, as such:

 

<ComboBox x:Name="PointsTool"

                  SelectedIndex="{Binding MySelectedIndex}"

                  ItemsSource="{Binding PointsComboItems}">

            <ComboBox.ItemTemplate>

                <DataTemplate>

                    <Image Source="{Binding}" Stretch="None"/>

                </DataTemplate>

            </ComboBox.ItemTemplate>

</ComboBox>

 

In the viewmodel, I have a property for PointsComboItems, like so:

public ItemsControl PointsComboItems

        {

            get { return this.pointsComboItems; }

            set { this.RaiseAndSetIfChanged(ref pointsComboItems, value); }

        }

 

and this ItemsControl get populated via the following method that gets called in the constructor of the viewmodel with this line:

     Task.Run(() => SetUpSymbolsAsync()).Wait();

 

and gets populated like this:

        private async void SetUpSymbolsAsync()

        {

            const int size = 24;

 

 

            try

            {

                var pinkOutlineSymbol = new SimpleLineSymbol() { Color = Colors.Pink, Style = SimpleLineStyle.Solid, Width = 2 };

 

 

                pointSymbols = new List<MarkerSymbol>()

                {

                    new SimpleMarkerSymbol() { Color = Colors.Red, Size = 15, Style = SimpleMarkerStyle.Circle, Outline = pinkOutlineSymbol },

                    new SimpleMarkerSymbol() { Color = Colors.Green, Size = 15, Style = SimpleMarkerStyle.Diamond, Outline = pinkOutlineSymbol },

                    new SimpleMarkerSymbol() { Color = Colors.Blue, Size = 15, Style = SimpleMarkerStyle.Square, Outline = pinkOutlineSymbol },

                    new SimpleMarkerSymbol() { Color = Colors.Purple, Size = 15, Style = SimpleMarkerStyle.X, Outline = pinkOutlineSymbol },

                };

 

 

                // Create image swatches for the UI

                Task<ImageSource>[] swatchTasks = pointSymbols.Select(symbol => symbol.CreateSwatchAsync(size, size, 96.0, Colors.Transparent)).ToArray();

 

 

                pointsComboItems.ItemsSource = await Task.WhenAll(swatchTasks);

            }

            catch (Exception ex)

            {

                Debug.WriteLine("Error: " + ex.Message);

            }

        }

 

I get an exception thrown at:

pointsComboItems.ItemsSource = await Task.WhenAll(swatchTasks);

 

that gives the "The calling thread cannot access this object because a different thread owns it." error as included in the pictures.

 

When I try to replace this one line with this instead:

                System.Windows.Application.Current.Dispatcher.Invoke((System.Windows.Forms.MethodInvoker)async delegate ()

                {

                    pointsComboItems.ItemsSource = await Task.WhenAll(swatchTasks);

                }, DispatcherPriority.Normal, null);

 

the compiler gets stuck inside there and continues running without anything actually showing.

 

My implementation is entirely based on how Esri did it in their ArcGISRuntime.Samples.Desktop solution, in MarkerSymbols.xaml, with the attempt to put everything in a MVVM pattern instead of just putting everything in the code-behind.

 

Please tell me how I can put their symbols into my UI or what I'm doing wrong here because I don't know if it's issues with the async methods vs. the UI threads or if something essential is just missing from my code.

 

Thank you!

Outcomes