wpf 修改代码隐藏中的属性不会更新列表框的ItemsTemplate中的DataContext绑定

lnlaulya  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(169)

我做了一个测试项目来演示我的问题。
在主窗口中,我定义了一个ListBox和它的ItemTemplate,沿着一个按钮 Update
DataTemplate中,我定义了一个CheckBox,其中IsChecked绑定到IsUsed属性。

<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>

项目的业务对象:

namespace Tests;

public class Foo
{
    public Foo(bool isUsed) => IsUsed = isUsed;

    public bool IsUsed { get; set; }

    public override string ToString() => IsUsed.ToString();
}

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;
        }
    }
}
  • 更新 * 按钮可反转所选项的布尔属性IsUsed

执行程序会显示第一个项目的复选框已选中,这是应该的。

但是,单击 Update 不会取消选中该复选框(即使应该取消选中),因为它会将IsUsed属性设置为false

我想我需要修改绑定来解决这个问题。
这个问题并不局限于布尔型,我用其他类型测试过。

e0uiprwp

e0uiprwp1#

当更改后面的任何属性时,您需要将此更改通知给UI以便绑定知道。

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();
    }

如果您需要通过UI进行更改,请将复选框绑定更改为双向:)

<CheckBox IsChecked="{Binding IsUsed, Mode=TwoWay}"/>

对不起我的英语:/

相关问题