Fernando
Fernando

Reputation: 39

Add items to combobox as checkbox

Hello I am using XAML/WPF to create a Combobox and then using an XML to populate it

Using the suggestion below this is my updated code and now it works!!

This is my XAML using the suggestions given below

    <ComboBox x:Name="customer_comboBox" HorizontalAlignment="Left" Margin="83,259,0,0" VerticalAlignment="Top" Width="172" SelectionChanged="customer_comboBox_SelectionChanged" >
         <ComboBox.ItemTemplate>
             <DataTemplate>
                    <CheckBox Content="{Binding}"/>
            </DataTemplate>
         </ComboBox.ItemTemplate>
    </ComboBox>

This is my XML

<?xml version="1.0" encoding="utf-8" ?>
<ComboBox>
  <Customer name="John">
    <Data>
      <System>Linux</System>
    </Data>
  </Customer>
  <Customer name="Fernando">
    <Data>
      <System>Microsoft</System>
      <System>Mac</System>
    </Data>
  </Customer>
</ComboBox>

And this is the code that is used to populate the customer_comboBox

 XmlDocument doc = new XmlDocument();
 doc.Load(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +@"\comboBox.xml");
 XmlNodeList customerList = doc.SelectNodes("ComboBox/Customer");
 List<string> customers = new List<string>();

 foreach (XmlNode node in customerList)
 {
     customers.Add(child.InnerText);
 }
 customer_comboBox.ItemsSource = customers;

All this works but I would like to have the added items inside the Combobox be in the form of a checklist I done it through the XAML by adding Checkbox items manually but since I am populating the combobox automatically by reading the XML I like to do it through code. I assume I need to do some type of Data Binding but I do not know how and the answers I seen here are a few years old which reference DataSource which its not a Combobox attribute anymore

Upvotes: 0

Views: 418

Answers (2)

Arie
Arie

Reputation: 5373

First, create a business class:

public class Customer: INotifyPropertyChanged
{
    // INotifyPropertyChanged implementation
    public virtual event PropertyChangedEventHandler PropertyChanged;
    public virtual void NotifyPropertyChanged(string propName)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    
    public string Name { get; set; }

    // Property to build to IsChecked of CheckBox
    public bool IsSelected { get; set; }
}

Then, the checkbox will look like this (you may databind it later; although if you want to dynamically add/delete items from the ComboBox during runtime, my advice is to use something other than IList as a databound ItemsSource, for example some implementation of ObservableCollection)

    <ComboBox Name="cbx">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding IsSelected}"
                       Width="20" />
                    <TextBlock Text="{Binding Name}"
                       Width="100" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

Here is how you populate the ComboBox with data:

        List<Customer> customers = new List<Customer>();
        // populate list instead of ComboBox from xml data source here...

        // then set the list as source
        cbx.ItemsSource = customers;

Later, to get selected items:

 List<Customer> selectedCustomers = ((List<Customer>)cbx.ItemsSource)
     .Where(a => a.IsSelected).ToList();

Upvotes: 0

Vytautas Plečkaitis
Vytautas Plečkaitis

Reputation: 861

Simpliest way would be : in XAML

<ComboBox x:Name="customer_comboBox" ...all other themings...>
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <CheckBox Content="{Binding Name}"/>
    </DataTemplate>
  </ComboBox.ItemTemplate>
</ComboBox>

For simplicity created data model class called Customer

public class Customer
{
  public string Name {get;set;}
}

Then your method would be like

XmlDocument doc = new XmlDocument();
 doc.Load(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +@"\comboBox.xml");
 XmlNodeList customerList = doc.SelectNodes("ComboBox/Customer");

List<Customer> customers = new List<Customer>()

 foreach (XmlNode node in customerList)
 {
   customers.Add(new Customer(){ Name = node.Attributes["name"].InnerText });
 }

customer_comboBox.ItemsSource = customers;

Upvotes: 1

Related Questions