我正在使用以下(简化)代码在ItemsControl中显示除第一个之外的所有项目中的元素:
<TheElement Visibility="{Binding RelativeSource={RelativeSource PreviousData},
Converter={StaticResource NullToVisibility}}/>
NullToVisibility
是一个简单的转换器,如果源为空,则返回Visibility.Hidden
,否则返回Visibility.Visible
。
现在,这在最初绑定视图或向列表添加元素(ObservableCollection
)时工作正常,但删除第一个元素时,第二个元素上的元素不可见
有关如何解决此问题的任何想法?
答案 0 :(得分:7)
从先前的答案中遗留了一些浪费的代码......不妨在这里使用它:
关键是刷新视图源,例如:
CollectionViewSource.GetDefaultView(this.Categories).Refresh();
下面的完整示例源。 删除第一个项目删除第一个元素并刷新视图:
<UserControl x:Class="WpfApplication1.RelativeSourceTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:PersonTests="clr-namespace:WpfApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<PersonTests:NullToVisibilityConvertor x:Key="NullToVisibility"/>
</UserControl.Resources>
<Grid>
<StackPanel Background="White">
<Button Content="Remove First Item" Click="Button_Click"/>
<ListBox ItemsSource="{Binding Categories}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" >
<StackPanel>
<TextBlock Text="{Binding CategoryName}"/>
<TextBlock Text="Not The First"
Visibility="{Binding RelativeSource={RelativeSource PreviousData},
Converter={StaticResource NullToVisibility}}"/>
</StackPanel>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
</UserControl>
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfApplication1
{
public partial class RelativeSourceTest : UserControl
{
public ObservableCollection<Category> Categories { get; set; }
public RelativeSourceTest()
{
InitializeComponent();
this.Categories = new ObservableCollection<Category>()
{
new Category() {CategoryName = "Category 1"},
new Category() {CategoryName = "Category 2"},
new Category() {CategoryName = "Category 3"},
new Category() {CategoryName = "Category 4"}
};
this.DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Categories.RemoveAt(0);
CollectionViewSource.GetDefaultView(this.Categories).Refresh();
}
}
}
using System.ComponentModel;
namespace WpfApplication1
{
public class Category : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _checked;
public bool Checked
{
get { return _checked; }
set
{
if (_checked != value)
{
_checked = value;
SendPropertyChanged("Checked");
}
}
}
private string _categoryName;
public string CategoryName
{
get { return _categoryName; }
set
{
if (_categoryName != value)
{
_categoryName = value;
SendPropertyChanged("CategoryName");
}
}
}
public virtual void SendPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
答案 1 :(得分:1)
现在已经开始了,但问题出在这里。 MVVM方法(我认为):
include(dirname(__FILE__).'/../../config/config.inc.php');
require_once('mymodule.php');
$products = MyModule::getAllProducts();
和用法:
public class PreviousDataRefreshBehavior : Behavior<ItemsControl> {
protected override void OnAttached() {
var col = (INotifyCollectionChanged)AssociatedObject.Items;
col.CollectionChanged += OnCollectionChanged;
}
protected override void OnDetaching() {
var col = (INotifyCollectionChanged)AssociatedObject.Items;
col.CollectionChanged -= OnCollectionChanged;
}
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
if(e.Action != NotifyCollectionChangedAction.Remove) {
return;
}
CollectionViewSource.GetDefaultView(AssociatedObject.ItemsSource).Refresh();
}
}
答案 2 :(得分:0)
删除后必须刷新底层CollectionViewSource
。
CollectionViewSource.GetDefaultView(this.Items).Refresh();