c# - WPF ListBox 属性绑定(bind)不更新

标签 c# wpf mvvm binding listbox

我有以下设置:

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

II项目:

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

我将数据库中的 IItem 列表的实现填充到列表中,如果 HasInformation 为真,则信息图标会正确显示。这一切都正常工作。

但是,如果我手动设置 HasInformation, View 不会更新。我试过:

在 View 模型中:

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,但是 View 永远不会更新,图标也永远不会显示。我已经确保我更新的项目的 HasInformation 属性确实如此,事实上,保持 true 。我已附加到 PropertyChanged 事件以确保它触发 "MyItems" 的属性更改(实际上,这也会触发 getter),我什至确保它使用 HasInformation 属性的正确值调用值转换器(是!),那我错过了什么?我没有正确处理图像显示/隐藏或可见性值转换有什么奇怪的地方吗?

最佳答案

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

View 模型

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

项目

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

关于c# - WPF ListBox 属性绑定(bind)不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22547062/

相关文章:

c# - 在应用程序文件中找不到名为 "...Entities"的连接字符串,但它存在吗?

wpf - 如何禁用 AutoSuggestBox 上的拼写检查器

data-binding - 如何在具有元素绑定(bind)的 ComboBox 中设置 SelectedIndex?

c# - MVVM 从 View 读取数据到模型

C# MVVM 如何将命令添加到 TextBlock

c# - 在 C# 中重绘气球提示和工具提示?

c# - Javascript DATE 和 C# date - 什么是最好的解决方案?

c# - R# 设置中 'Local constants' 和 'Constant fields' 之间的差异?

c# - 网格边框/单元格之间的间隙

c# - 为什么这些除法方程的结果为零?