2

WPF + XAML + MVVM 堆栈的新手,所以我确定我在这里做了一些基本的事情,但谷歌搜索并没有帮助我弄清楚。我认为第二双眼睛可能会有所帮助。

设置

  • 我有一个名为 FilesToAdd 的对象列表
  • 我有一个绑定到此列表的 DataGrid
  • 我有一个触发处理代码的拖放事件
    • 我已经通过Console.WriteLine()输出确认了这个工作。

目标

  • 当一个项目被添加到列表中时,我希望使用刚刚添加到列表中的适当信息来更新数据网格。

问题

  • 该列表似乎已更新,但数据网格从未更新。

编码

仅显示相关部分。

UploaderViewModel 类

private ObservableCollection<IAddableFile> _filesToAdd;
public event PropertyChangedEventHandler PropertyChanged;

       public UploaderViewModel()
       {
         _filesToAdd = new ObservableCollection<IAddableFile>();

        }

        protected virtual void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }


        public ObservableCollection<IAddableFile> FilesToAdd 
        {
            get { return _filesToAdd; }
            set
            {
                if (value != _filesToAdd)
                {
                    _filesToAdd = value;
                OnPropertyChanged("FilesToAdd");
                OnPropertyChanged("FilesAreQueued");
                }
            }
        }

        public bool FilesAreQueued
        {
            get { return (FilesToAdd.Count > 0); }
        }

        public void AFileHasBeenAdded(string filepath)
        {
                        var message = String.Format("File dropped: {0}", filepath);
                        Console.WriteLine(message);

            var newFileInfo = new FileInfo(filepath);
            if (newFileInfo.Exists && newFileInfo.Length > 0 && (!FileIsADirectory(newFileInfo))) // only add the file to the ViewModel if it's 
            {
                FilesToAdd.Add(new FileSystemFile(newFileInfo)); //Creating our own type becaause we do additional things with it
                Console.WriteLine(String.Format("File added to list: {0}", newFileInfo.FullName));
            }
        }

XAML 绑定

<DataGrid ItemsSource="{Binding FilesToAdd}" Height="100" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="100" AutoGenerateColumns="False" Visibility="{Binding FilesAreQueued, Converter={StaticResource BoolToVisConverter}}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="File Name" Binding="{Binding FileName}"/>
        <DataGridTextColumn Header="Size" Binding="{Binding FileSizeInText}"/>
    </DataGrid.Columns>
</DataGrid>

我错过了什么?我一直在看这个模式,我知道它一定很简单,因为我盯着屏幕太久而看不到。:)

4

1 回答 1

3

编辑:我怀疑DataGrid更新很好,但你看不到它,因为FilesAreQueued属性在撒谎。

你需要类似的东西

FilesToAdd.CollectionChanged += (s,e) =>
    OnPropertyChanged("FilesAreQueued");

由于您只想这样做一次(如果有的话,可以FilesToAdd.Count直接绑定到),您真的应该选择一个readonly集合字段。


DataContext如果视图实际上是那个视图模型,看起来很好。

另一个问题可能是该类没有实现INotifyPropertyChanged(您可以在没有实际实现的情况下使用事件来实现它class : interface),这仅在您FilesToAdd用新实例覆盖该属性时才适用。(一般来说,我将集合公开为get-only 带有一个readonly字段。)

可能想要检查绑定错误(但不要认为你得到任何绑定到 null 的错误DataContext)。

(我也建议使OnPropertyChanged线程安全,即var handler = <event>; if (handler != null) handler();

于 2013-08-06T17:00:14.900 回答