WPF ListBox属性绑定未更新

本文关键字:更新 绑定 属性 ListBox WPF | 更新日期: 2023-09-27 17:51:12

我有以下设置:

XAML:

<ListBox x:Name="MyList" ItemsSource="{Binding MyItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Height="20" Width="20" Visibility="{Binding HasInformation, Converter={StaticResource VC}, ConverterParameter=True}" Source="/path/to/information.png" />
                <TextBlock Text="{Binding Name}" VerticalAlignment="Center" Padding="5,0" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

注意:ConverterParameter被传递在简单地控制是否可见性是"崩溃"(False),或"隐藏"(True),所以在这种情况下,我想要的可见性是Hidden

ViewModel片段:

private ObservableCollection<IItem> _MyItems;
public ObservableCollection<IItem> MyItems
{
    get
    {
        return _MyItems;
    }
    set
    {
        NotifyPropertyChanged(ref _MyItems, value, "MyItems");
    }
}
private IItem _SelectedItem;
public IItem SelectedItem
{
    get
    {
        return _SelectedItem;
    }
    set
    {
        NotifyPropertyChanged(ref _SelectedItem, value, "SelectedItem");
    }
}

IItem:

public interface IItem
{
    string Name { get; }
    bool HasInformation { get; set; }
}

我将数据库中的IItem列表的实现填充到列表中,如果HasInformation为真,则信息图标将适当地出现。

然而,如果我手动设置HasInformation,视图不会更新。我试过了:

在ViewModel中:

OnPropertyChanged("MyItems");
MyItems[MyItems.IndexOf(SelectedItem)].HasInformation = true;
// Note that "SelectedItem" is persisted correctly, and always
// points to the selected item that we want to update.

后面的代码:

MyList.GetBindingExpression(ItemsControl.ItemsSourceProperty).UpdateTarget();

所有这些都触发了MyItems属性的getter, ,但是视图永远不会更新,图标也永远不会显示。我已经确保我更新的项目的HasInformation属性实际上仍然是true。我已经附加到PropertyChanged事件,以确保它触发"MyItems"的属性更改(它是,这也触发getter),我甚至已经确保它调用值转换器与HasInformation属性的正确值(它是!),所以我错过了什么?是否有一些奇怪的图像显示/隐藏或可见性值转换,我没有正确处理?

WPF ListBox属性绑定未更新

ObservableCollection只通知集合的更改,而不通知每个项的更改。为了实现您的目标,其中一个选项是将IItem从接口更改为实现INotifyPropertyChanged接口的类(或在IItem具体类型中实现它),并将其与ViewModel的PropertyChanged委托挂钩(记得取消订阅它)。请看下面我的一些代码。

ViewModel

public class MyViewModel: INotifyPropertyChanged
{
    private ObservableCollection<Item> _MyItems;
    public ObservableCollection<Item> MyItems
    {
        get
        {
            return _MyItems;
        }
        set
        {
            if (_MyItems != null)
            {
                foreach (var item in _MyItems)
                {
                    item.PropertyChanged -= PropertyChanged;
                }
            }
            if (value != null)
            {
                foreach (var item in value)
                {
                    item.PropertyChanged += PropertyChanged;
                }
            }
            OnPropertyChanged();
        }
    }
    private Item _SelectedItem;
    public Item SelectedItem
    {
        get
        {
            return _SelectedItem;
        }
        set
        {
            _SelectedItem = value;
            OnPropertyChanged();
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
<<p> 项/strong>
public class Item : INotifyPropertyChanged
{
    private string _name;
    private bool _hasInformation;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }
    public bool HasInformation
    {
        get { return _hasInformation; }
        set
        {
            _hasInformation = value;
            OnPropertyChanged();
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}