GettingStarted
GettingStarted

Reputation: 7605

How to update a CheckedListItem using WPF

One of my classes

public class CheckedListItem<T> : INotifyPropertyChanged

has the method

    public bool IsChecked
    {
        get { return isChecked; }
        set
        {
            isChecked = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
            }
        }
    }

My XAML looks like

    <ListBox ItemsSource="{Binding Employee}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Item.Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

My employee.cs file

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

I cant figure out how I can write back to the database when a item is checked or unchecked.

I would appreciate any help and would be more than happy to post the entire code for any files you need to see.

Upvotes: 0

Views: 167

Answers (1)

Joakim Hansson
Joakim Hansson

Reputation: 544

You should be able to get what you want by adding TwoWay for mode and PropertyChanged on UpdateSourceTrigger.

Final XAML will then be:

<ListBox ItemsSource="{Binding Employee}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Content="{Binding Path=Item.Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

EDIT: By the way, I think you might be setting your ItemsSource incorrectly. I'm sure what you want is to bind that listbox to a collection of Employees?

Something like:

    public ObservableCollection<Employee> Employees 
    {
        get { return _employees; }
        set
        {
           _employees = value;
           if (PropertyChanged != null)
              {
                PropertyChanged(this, new PropertyChangedEventArgs("Employees"));
            }
        }
  }

I misunderstood the question so here comes second edit:

Your class files would instead look like this:

 public partial class MainWindow : INotifyPropertyChanged
{
    private ObservableCollection<MutableKeyValuePair<Employee, bool>> _employees;

    public MainWindow()
    {
        InitializeComponent();

        Employees = new ObservableCollection<MutableKeyValuePair<Employee, bool>>
        {
            new MutableKeyValuePair<Employee, bool>(new Employee("Joakim"), false),
            new MutableKeyValuePair<Employee, bool>(new Employee("SoftwareIsFun"), false),
        };
    }

    public ObservableCollection<MutableKeyValuePair<Employee, bool>> Employees
    {
        get { return _employees; }
        set
        {
            _employees = value;
            OnPropertyChanged(nameof(Employees));
        }
    }

    public void UpdateDatabase()
    {
        foreach (var employee in Employees)
        {
            if (employee.Value)
            {
                //DATABASE LOGIC HERE
            }
        }
    }
}

public class MutableKeyValuePair<TKey, TValue>
{
    public TKey Key { get; set; }
    public TValue Value { get; set; }

    public MutableKeyValuePair()
    {

    }

    public MutableKeyValuePair(TKey key, TValue value)
    {
        Key = key;
        Value = value;
    }
}

public class Employee
{

    public Employee(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}

XAML:

<DataGrid ItemsSource="{Binding Employees}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Key.Name}"/>
            <DataGridCheckBoxColumn Binding="{Binding Value}"/>
        </DataGrid.Columns>
    </DataGrid>

enter image description here

Upvotes: 1

Related Questions