Listview没有在propertychange上更新

时间:2017-07-28 21:59:48

标签: c# wpf listview mvvm

当我在列表中添加/删除项目列表视图时,会相应地添加/删除项目。但是当我更改列表的属性,导致不同的ToString()值时,Listview不会相应地更新更改。如果我从xml文件重新启动应用程序后重新加载数据,ListView会相应地显示它的项目。所以我想我可以用我的ToString方法排除一个问题。或者这是一个我正在使用ToSTring()的问题?

有谁知道这个问题的解决方案?

window.xaml:

<Window x:Class="WpfApplication1.MainWin"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    DataContext="MainWindowViewModel"
    Title="Baronieverwaltung für DSA" Height="1000" Width="1500" 
    WindowStartupLocation="CenterScreen" 
    WindowStyle="ThreeDBorderWindow">
    <GroupBox  Grid.Row="7" Grid.ColumnSpan="4" Header="Angestellte">
        <ListView Height="200" ItemsSource="{Binding DieBaronie.Angestellte, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding SelectedAngestellterIndex}">

MainWindowViewModel.cs:

public class MainWindowViewModel : INotifyPropertyChanged
{            
public Baronie DieBaronie { get; set; }

private void MethodThatChangesListViewItem()
{
        if (SelectedAngestellterIndex > -1)
        {
            DieBaronie.Angestellte[SelectedAngestellterIndex].FunktionWarenschau = true;
        }
        //I found some threads where the solution was some variation of 
        //those NotifyPropertyChanged... but none work :(
        NotifyPropertyChanged("DieBaronie.Angestellte"); 
        NotifyPropertyChanged("DieBaronie");
        NotifyPropertyChanged("");
        NotifyPropertyChanged(null);

}

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (null != handler)
    {
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

DieBaronie.cs:

public class Baronie
{
  public ObservableCollection<Angestellter> Angestellte { get; set; }

Angestellter.cs:

public class Angestellter : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private Boolean _FunktionWarenschau { get; set; }
    public Boolean FunktionWarenschau
    {
        get
        {
            return _FunktionWarenschau;
        }
        set
        {
            //if i add a break point here, the debugger stops here as expected - with the correct value
            _FunktionWarenschau = value; 
            NotifyPropertyChanged();
        }
    }
    //Method doesn't even get called after the change :(
    public override string ToString()
    {
        String val = Name + " ";
        if (_FunktionWarenschau)
        {
            val += "(Warenschau)";
        }
        return val;
    }

1 个答案:

答案 0 :(得分:1)

与您的建议一样,问题在于ToString() - 这不是属性,因此WPF绑定引擎不知道是否需要刷新视图。

此外,对于更复杂的MVVM场景,我认为无论如何都要使用Properties,因为您可以构建视图以显示更复杂的数据(例如图像)或进一步自定义数据布局(例如图像+字符串)。

要解决您的问题,我建议:

  1. 在ViewModel中创建要绑定的属性。在这里,您可以简单地绑定到FunktionWarenschau和Name。或者,您可以创建一个新的字符串属性,并让FunktionWarenschau更新您的字符串属性,或者只是使用传入的新属性名称调用NotifyPropertyChanged。

  2. 为ListView创建一个DataTemplate(未经测试的代码为您提供一种风格)

    <ListView Height="200"
              ItemsSource="{Binding DieBaronie.Angestellte, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              SelectedIndex="{Binding SelectedAngestellterIndex}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding FunktionWarenschau}"/>
                        <TextBlock Text="{Binding Name}"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>