拖放时PropertyChanged为null

时间:2017-09-04 07:34:28

标签: c# wpf xaml data-binding

可能有一些解决方案,但到目前为止,我找不到解决方案是不成功的。任何帮助,将不胜感激。目前,我有一个对话框,我可以通过单击按钮或从文件资源管理器中拖放文件来上传文件。该对话框包含绑定DataGrid的{​​{1}}。 ObservableCollection<FileDetails>的事件处理程序也已附加到此属性。当我通过按钮添加文件时,单击PropertyChanged事件并使用添加的文件更新UI。但是,当我将文件拖放到dataGrid时,PropertyChanged处理程序为null。

以下是我的ViewModel:

PropertyChanged

以下是我的XAML代码的一部分

public class FileUploadVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private static ObservableCollection<FileDetails> m_DialogFiles;
    public ObservableCollection<FileDetails> DialogFiles
    {
        get
        {
            return m_DialogFiles ?? new ObservableCollection<FileDetails>();
        }
        set
        {
            m_DialogFiles = value;
            this.NotifyPropertyChanged(nameof(DialogFiles));
        }
    }

    public ICommand FileUpload
    {
        get
        {
            return new SimpleCommand(AddFiles);
        }
    }

    private void AddFiles(object obj)
    {
        OpenFileDialog openFile = new OpenFileDialog();
        openFile.Multiselect = true;
        if (openFile.ShowDialog() == true)
        {
            m_fileList = openFile.FileNames.ToList();
            GetFileWithIcon();
        }
        DialogFiles = new ObservableCollection<FileDetails>(dgFiles);
    }
}

这就是CodeBehind

<Grid ShowGridLines="False">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <DataGrid x:Name="dataGrid1" Height="100" ItemsSource="{Binding Path=DialogFiles, UpdateSourceTrigger=PropertyChanged}" CanUserAddRows="False"  AutoGenerateColumns="False" 
              GridLinesVisibility="None" CanUserDeleteRows="True" HeadersVisibility="None" AllowDrop="True" Drop="dataGrid1_Drop">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Image Source="{Binding FileIcon}" Height="20" Width="20"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding FileName}" Width="Auto"></DataGridTextColumn>
            <DataGridTemplateColumn Width="Auto">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Command="Delete">
                            <Image Source="/AssemblyName;component/Resources/delete_icon.png" Height="15" Width="20"/>
                        </Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
    <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
        <Button Width="60" Margin="10" Command="{Binding Path=FileUpload}">Add Files</Button>
        <Button Width="60" Margin="10">Upload</Button>
    </StackPanel>
</Grid>

如上所述,单击AddFiles可以正常工作,但是尽管DialogFiles的值不在内,拖放也不会触发PropertyChanged。

1 个答案:

答案 0 :(得分:1)

Akshatha

我发现您的解决方案存在一些问题:

问题1 - 如果查看以下代码,则错误地设置了DataContext(ViewModel):

public FileUploadVM FileUpload {
    get {
        return new FileUploadVM();
    }
}

每次请求ViewModel对象时,上面的代码都会创建ViewModel的新实例。这意味着无论何时调用此对象:

FileUploadVM.m_fileList.Clear();

它将创建一个新对象,并将破坏对DataContext的引用(View - &gt; ViewModel)。

修改 您可以通过创建普通属性来检索ViewModel对象并在每次需要访问ViewModel时使用此实例来解决此问题:

private FileUploadVM fileUploadVM = new FileUploadVM();

public FileUploadVM FileUploadVM {
    get { return this.fileUploadVM; }
    set {
        if (this.fileUploadVM != value) {
            this.fileUploadVM = value;
        }
    }
}

问题2 :重新初始化DialogFiles集合时会破坏引用:

FileUploadVM.DialogFiles = new ObservableCollection<FileDetails>(FileUploadVM.dgFiles);

每当您创建此对象的新实例时,都需要通知您的视图有一个需要绑定的新集合,而不是使用您不再使用的“旧”集合。确保始终使用集合的正确实例的一种方法是将其设置为只读:

public ObservableCollection<FileDetails> DialogFiles {
    get {
        return m_DialogFiles;
    }
}

并且只添加/清除 集合的单个实例,所以不要这样做:

FileUploadVM.DialogFiles = new ObservableCollection<FileDetails>(FileUploadVM.dgFiles);

只读的原则不允许你这样做,而是用它来修改你的收藏:

FileUploadVM.DialogFiles.Add(new FileDetails("Your FileName"));

如果你应该从集合中删除/清除一个项目,你可以简单地使用

FileUploadVM.DialogFiles.Clear();
// OR
FileUploadVM.DialogFiles.Remove(myFileDetailsItem); 
// OR
FileUploadVM.DialogFiles.RemoveAt(index);

总结,您的问题是您在点击Drop方法时创建了DialogFiles集合的新实例:

FileUploadVM.DialogFiles = new ObservableCollection<FileDetails>(FileUploadVM.dgFiles);

你应该只是添加到该集合而不是重新声明实例:

foreach(var file in FileUploadVM.dgFiles) {
    FileUploadVM.DialogFiles.Add(file);
}