简体   繁体   English

WPF ListBox属性绑定未更新

[英]WPF ListBox property binding not updating

I have the following setup: 我有以下设置:

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

Note: The ConverterParameter being passed in simply controls whether the visibility is "Collapsed" ( False ), or "Hidden" ( True ), so in this case, I want the visibility to be Hidden . 注意:传入的ConverterParameter只是控制可见性是“ Collapsed”( False )还是“ Hidden”( True ),因此在这种情况下,我希望可见性为Hidden

ViewModel Snippet: 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: IItem:

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

I populate an implementation of a list of IItem from a database into the list, and the information icon appears appropriately if HasInformation is true. 我将IItem列表的IItem从数据库填充到列表中,并且如果HasInformation为true,则会适当显示信息图标。 This all works correctly. 这一切都正常工作。

However, if I set HasInformation by hand, the view does not update. 但是,如果我手动设置HasInformation ,则视图不会更新。 I have tried: 我努力了:

In the ViewModel: 在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.

In the code behind: 在后面的代码中:

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

All of these fire the getter of the MyItems property, but the view never updates and the icon never displays. 所有这些都会激发MyItems属性的吸气剂, 但是视图永远不会更新,图标也永远不会显示。 I have ensured that the HasInformation property of the item that I updated does, in fact, remain true . 实际上,我确保我更新的项目的HasInformation属性确实保持为true I've attached to the PropertyChanged event to ensure that it's firing a property change for "MyItems" (it is, this also fires the getter), and I've even ensured that it's calling the value converter with the correct value for the HasInformation property (it is!), so what am I missing? 我已经附加了PropertyChanged事件,以确保它触发了"MyItems"的属性更改(即,这也触发了吸气剂),并且甚至确保它为HasInformation调用了具有正确值的值转换器。属性(是!),那么我想念的是什么? Is there something weird with image showing/hiding or visibility value conversion that I'm not handling correctly? 图片显示/隐藏或可见度值转换是否有些奇怪,我无法正确处理?

ObservableCollection only notifies the collection changes not the changes in each of the item. ObservableCollection仅通知集合更改,而不通知每个项目中的更改。 In order to achieve your goal one of options is to change the IItem from interface to a class which implements INotifyPropertyChanged interface (or implement it in the IItem concrete type), and hook it with the ViewModel's PropertyChanged delegate (remember to unsubscribe it). 为了实现您的目标,选项之一是将IItem从接口更改为实现INotifyPropertyChanged接口的类(或以IItem具体类型实现),并将其与ViewModel的PropertyChanged委托挂钩(请记住取消订阅)。 See some of my code below. 请参阅下面的一些代码。

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

Item 项目

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM