wpf – 删除集合元素时{RelativeSource PreviousData}的问题

我正在使用以下(简化)代码在ItemsControl中显示除第一个之外的所有项目中的元素:

<TheElement Visibility="{Binding RelativeSource={RelativeSource PreviousData},
                                 Converter={StaticResource NullToVisibility}}/>

NullToVisibility是一个简单的转换器,如果源为null,则返回Visibility.Hidden,否则返回Visibility.Visible.

现在,这在最初绑定视图或向列表添加元素(ObservableCollection)时工作正常,但在删除第一个元素时,元素在第二个元素上不会变得不可见.

有想法该怎么解决这个吗?

从先前的答案中遗留了一些浪费的代码……不妨在这里使用它:

关键是刷新视图源,例如:

CollectionViewSource.GetDefaultView(this.Categories).Refresh();

以下是完整示例源.删除第一项删除第一个元素并刷新视图:

RelativeSourceTest.xaml

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

RelativeSourceTest.xaml.cs

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

Category.cs

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));
            }
        }
    }
}
相关文章
相关标签/搜索