【问题标题】:ObservableCollection not updating ListView [duplicate]ObservableCollection 不更新 ListView [重复]
【发布时间】:2019-06-25 09:32:24
【问题描述】:

我知道,有很多这样的问题,但我无法让它工作......

我有一个带有字符串、布尔值的 ObservableCollection。 ListView 绑定到它,并有一个 CheckBox 和一个 TextBox。现在我需要通过代码检查一个项目...当我更改布尔值时,GUI 中没有出现任何内容。

当我检查 ListView 项目时,集合会更新。

ObservableCollections

public ObservableCollection<MvItems> Mailverteiler { get { return _Mailverteiler; } }
public ObservableCollection<MvItems> _Mailverteiler = new ObservableCollection<MvItems>();

public class MvItems
{
  public string MvName { get; set; }
  public bool IsChecked { get; set; }
}

如何“检查”一个项目:

foreach (MvItems mvitem in Mailverteiler)
{
  mvitem.IsChecked = false;
  if (mvitem.MvName.ToString().Contains(tblFirma.Text))
  {
    mvitem.IsChecked = true;
  }
}

XAML:

<ListView x:Name="lvMailverteiler" Margin="20,10,20,0" FontSize="9" SelectionMode="Extended" Height="260" ItemsSource="{Binding Mailverteiler}">    
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Width="280" VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition Width="230" />
                </Grid.ColumnDefinitions>
                <CheckBox Grid.Column="0" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
                <TextBlock Grid.Column="1" Text="{Binding MvName}" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

如何添加项目:

this.lvMailverteiler.ItemsSource = Mailverteiler;
_Mailverteiler.Add(new MvItems { MvName = group.DisplayName, IsChecked=false });

【问题讨论】:

    标签: c# wpf listview observablecollection


    【解决方案1】:

    问题是,ObservableCollection 在添加/删除/移动项目时引发 CollectionChanged 事件。 但是当其中一项的属性更新时,它不会引发 PropertyChanged 事件。

    您需要实现INotifyPropertyChanged 接口并在MvItems 类的属性设置器上引发PropertyChanged 事件。

    例如:

    public class MvItems : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void  RaisePropertyChanged(
                [System.Runtime.CompilerServices.CallerMemberName]
                string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        private string mvName;
        public string MvName
        {
            get => return mvName; 
            set
            {
                mvName = value;
                RaisePropertyChanged();
            }
        }
    
        private bool isChecked;
        public bool IsChecked
        {
            get => return isChecked; 
            set
            {
                isChecked = value;
                RaisePropertyChanged();
            }
        }
    }
    

    编辑:您会在互联网上找到许多关于如何在 setter 中引发 Propertychanged 事件的示例。 附带说明一下,我更喜欢使用 PropertyChanged.Fody,它会在实现 INotifyPropertyChanged 接口的类的设置器中自动添加“引发事件”代码行。

    【讨论】:

    • 您应该提供一些INotifyPropertyChanged 的示例实现以防万一。虽然......这可能是一个骗局
    • 虽然可能有各种编译器添加,但实际实现始终保持不变
    • 虽然,如果他开始自己实现它,他将无法再使用自动实现的属性。他必须添加私有字段并从属性获取器/设置器中检索/更改它们
    • 我编辑了示例以适合您的班级MvItems。你的类应该看起来像这样来实现INotifyPropertyChanged,这样当 IsChecked 发生变化时你的 GUI 就会更新。
    • 像魅力一样工作!非常感谢...刚刚公开了 ObservableCollection 并将get =&gt; return mvName; 更改为get { return isChecked; },现在一切都很好...谢谢!
    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 2014-11-02
    • 2017-04-22
    • 2019-10-25
    相关资源
    最近更新 更多