swabygw
swabygw

Reputation: 913

Dynamically Populate ComboBox Within A WPF ListView With Items

I have a WPF ListView which is bound to a data source. In the ListView are dynamically created ComboBoxes, which I would like to bind to another data source to provide the Items, but the SelectedIndex comes from the first data source (see XAML below).

Currently, the functionality works fine if the ComboBoxItems are coded statically into the XAML (shown commented out in the XAML below). But, I want to provide the ComboBoxItems (list of strings) dynamically, so I can expand the list, by either 1) binding to the a custom class (see my code-behind below), or 2) setting the DataSource in the WindowInitialized or WindowRendered event(s).

I've tried both ways, but here I'm showing an example of the first method that I tried. The XAML and VB code below doesn't error, but the ComboBoxes show up with empty drop-downs. Any ideas?

Also, the list of strings is, really, just a simple list of simple strings (but I want to make it a long list). Is there an easier way to populate the ComboBox? (Personally, I thought the second method was quite simpler to just create a VB List and set the datasource, but that had the same result)

EDIT: My solution was to, simply, create another Property(OfType String) within the datasource of the ListView and bind the ComboBox to the new Property. Here's how the new Property looks:

    Public ReadOnly Property myList As List(Of String)
        Get
            Dim cboxList As New List(Of String)
            For...
                cboxList.Add(New String("..."))
            Next
            Return cboxList
        End Get
    End Property

XAML:

<ListView IsSynchronizedWithCurrentItem="True" Margin="11,5,0,0" x:Name="myList" HorizontalAlignment="Left" Width="130" BorderBrush="{x:Null}" BorderThickness="0" Background="White" Height="240" VerticalAlignment="Top" Grid.Column="1" >
    <ListView.View>
    <GridView AllowsColumnReorder="False">
        <GridViewColumn Header="Freq" Width="55">
        <GridViewColumn.CellTemplate>
            <DataTemplate>
            <ComboBox HorizontalContentAlignment="Center"
                x:Name="_ListFrequencies"
                ItemsSource="{Binding TestStrings}"
                DisplayMemberPath="TestString"
                IsEnabled="{Binding outCustomValue1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                SelectionChanged="_OnSelectionChanged"
                SelectedIndex="{Binding outCustomValue2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                FontSize="10"/>
                                    <!--
                                        <ComboBoxItem Content="test"/>
                                        <ComboBoxItem Content="test"/>
                                        <ComboBoxItem Content="test"/>
                                        -->
            </DataTemplate>
        </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>
    </ListView.View>
</ListView>

Code-Behind

Public Class MyComboBoxItems

    Public Property TestStrings() As List(Of MyComboBoxStrings)

    Public Function MyComboBoxItems()
        TestStrings = New List(Of MyComboBoxStrings)
    End Function

End Class

Public Class MyComboBoxStrings

    Public ReadOnly Property TestString As String
        Get
            Return "test"
        End Get
    End Property

End Class

Upvotes: 1

Views: 1983

Answers (1)

AnjumSKhan
AnjumSKhan

Reputation: 9827

  1. You need a ViewModel for your scenario.

Corresponding C# code ( you can use it as pseudo-code ) :

public class ViewModel
    {
        public List<MyComboBoxItems> items { get; set; }
        public int outCustomValue2 { get; set; }
        public bool outCustomValue1 { get; set; }

        public ViewModel()
        {
            items = new List<MyComboBoxItems>();
            items.Add(new MyComboBoxItems());
            items.Add(new MyComboBoxItems());
            items.Add(new MyComboBoxItems());
            items.Add(new MyComboBoxItems());
        }
    }

    public class MyComboBoxItems
    {
        public List<MyComboBoxStrings> TestStrings { get; set; }       

        public MyComboBoxItems()
        {
            TestStrings = new List<MyComboBoxStrings>();
            TestStrings.Add(new MyComboBoxStrings("val1"));
            TestStrings.Add(new MyComboBoxStrings("val1"));
            TestStrings.Add(new MyComboBoxStrings("val1"));
            TestStrings.Add(new MyComboBoxStrings("val1"));
        }
    }

    public class MyComboBoxStrings
    {
        string _testString;
        public string TestString { get { return _testString; } }

        public MyComboBoxStrings(string value)
        {
            _testString = value;
        }
    }

apply DataContext :

 ViewModel vm = new ViewModel();
 myList.DataContext = vm;

Upvotes: 0

Related Questions