I made a test project to demonstrate my issue.
In the main window, I define a ListBox
and it's ItemTemplate
, along with 1 button, Update.
In the DataTemplate
I define a CheckBox
with IsChecked
bound to the IsUsed
property.
<Window x:Class="Tests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<WrapPanel>
<ListBox x:Name="listBox">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsUsed}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Update" Click="ButtonUpdate_Click"/>
</WrapPanel>
</Window>
Business object for items:
namespace Tests;
public class Foo
{
public Foo(bool isUsed) => IsUsed = isUsed;
public bool IsUsed { get; set; }
public override string ToString() => IsUsed.ToString();
}
Code behind for MainWindow:
using System.Windows;
namespace Tests;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
listBox.ItemsSource = new Foo[]
{
new(true),
new(false),
};
}
private void ButtonUpdate_Click(object sender, RoutedEventArgs e)
{
Foo? SelectedItem = (Foo)listBox.SelectedItem;
if (SelectedItem is not null)
{
SelectedItem.IsUsed = false;
}
}
}
The Update button inverts the boolean property IsUsed
of the selected item.
Executing the program shows that the first item's checkbox is checked, as it should be.
However, clicking on Update doesn't uncheck the checkbox even though it should, since it sets IsUsed
property to false
.
I guess I need to modify the binding to fix the problem.
This problem isn't specific to booleans, I tested with other types.
CodePudding user response:
When change any property in behind, you need notify to UI this change for bind know.
public class Foo : INotifyPropertyChanged
{
#region INotifyPropertyChanged implementos
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
private bool isUsed;
public Foo(bool isUsed) => IsUsed = isUsed;
public bool IsUsed { get => isUsed; set { isUsed = value; RaisePropertyChanged(); } }
public override string ToString() => IsUsed.ToString();
}
and change Checkbox bind to twoway if you need change by UI :)
<CheckBox IsChecked="{Binding IsUsed, Mode=TwoWay}"/>
sorry about my english :/