我有以下设置:
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/