Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法将COM对象强制转换为类类型_C#_Exception_Uwp_Com_Runtimeexception - Fatal编程技术网

C# 无法将COM对象强制转换为类类型

C# 无法将COM对象强制转换为类类型,c#,exception,uwp,com,runtimeexception,C#,Exception,Uwp,Com,Runtimeexception,我正在制作一个图书馆管理软件。我已经将数据库的管理分离到一个单独的c#库“DataAccessLibrary”。它包含DataAccess.cs: public static event MyDelegate Event_AddBook; public static void InitializeDatabase() { using (SqliteConnection db = new SqliteConnection("Filename=MyBooks.db"

我正在制作一个图书馆管理软件。我已经将数据库的管理分离到一个单独的c#库“DataAccessLibrary”。它包含DataAccess.cs:

public static event MyDelegate Event_AddBook;

    public static void InitializeDatabase()
    {
        using (SqliteConnection db = new SqliteConnection("Filename=MyBooks.db"))
        {
            db.Open();

            //Not necessary
        }
    }

    public static void AddBook(Book book)
    {
        Event_AddBook.Invoke(book);

        using (SqliteConnection db = new SqliteConnection("Filename=MyBooks.db"))
        {
            db.Open();
            //Not necessary
        }            
    }

    public static ObservableCollection<Book> GetBooks()
    {
        ObservableCollection<Book> books = new ObservableCollection<Book>();

        using (SqliteConnection db = new SqliteConnection("Filename=MyBooks.db"))
        {
            db.Open();
            //Not necessary
        }

        return books;
    }
}
事件“event\u AddBook”由YourBooks类订阅:

public sealed partial class YourBooks_View : Page
{
    private BooksViewModel ViewModel { get; set; } = new BooksViewModel();

    public YourBooks_View()
    {
        this.InitializeComponent();
        DataAccess.Event_AddBook += new MyDelegate(this.GridView_AddBook);
    }

    private void GridView_AddBook(Book book)
    {
        ViewModel.Books.Add(book);
    }
}
代码编译时没有错误,但在运行时,当我添加图书时,在YourBooks\u View.GridView\u AddBook()行抛出此异常:

System.InvalidCastException HResult=0x80004002 Message=无法将类型为“System.Collections.Specialized.NotifyCollectionChangedEventHandler”的COM对象强制转换为类型为“System.Collections.Specialized.NotifyCollectionChangedEventHandler”的类。表示COM组件的类型实例不能转换为不表示COM组件的类型;但是,只要底层COM组件支持对接口IID的QueryInterface调用,就可以将它们转换为接口。 Source=System.Private.CoreLib 堆栈跟踪: 位于System.StubHelpers.StubHelpers.GetCOMIPFromRCW_WinRTDelegate(对象objSrc、IntPtr pCPCMD、IntPtr和ppTarget) 位于System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(对象发送方,NotifyCollectionChangedEventArgs e) 位于System.Collections.ObjectModel.ObservableCollection
1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
位于System.Collections.ObjectModel.ObservableCollection
1.InsertItem(Int32索引,T项) 位于System.Collections.ObjectModel.Collection`1.Add(T项) 在C:\Users\Hemil\source\repos\Bookshelf\Bookshelf\YourBooks\u View.xaml.cs中的Bookshelf.YourBooks\u View.GridView\u AddBook(Book Book Book Book)中 在C:\Users\Hemil\source\repos\Bookshelf\DataAccessLibrary\DataAccess.cs中的DataAccessLibrary.DataAccess.AddBook(Book Book Book)中:第44行 在C:\Users\Hemil\source\repos\Bookshelf\Bookshelf\NewBook\u View.xaml.cs中的Bookshelf.NewBook\u View.d\u 3.MoveNext()中

我不知道这是什么意思。是否有办法解决此问题,或者是否有办法以其他方式通知视图

我的c不太好。请原谅我的任何错误或愚蠢的问题

编辑:我正在使用Microsoft.Data.Sqlite容器中提供的Sqlite数据库

编辑:我遵循了本教程:。我的目标是最新的Windows 10,因此我的应用程序中没有包含Sqlite

编辑:我将整个源代码上传到gitlab上的公共存储库,如下所示:

编辑:我想我也应该包括BookViewModel源代码。好的,给你:

public class BooksViewModel
{
    private ObservableCollection<Book> books { get; set; }

    public ObservableCollection<Book> Books
    {
        get { return this.books; }

        set
        {
            this.books = value;
        }
    }


    public BooksViewModel()
    {
        books = DataAccess.GetBooks();
    }
}
public类booksview模型
{
私人可观察收集书籍{get;set;}
公开收集书籍
{
获取{返回this.books;}
设置
{
这就是价值;
}
}
公共图书视图模型()
{
books=DataAccess.GetBooks();
}
}

您试图添加到集合中的图书对象可能已附加到数据库,当您对数据库执行操作时,请确保处置其上下文(这取决于您使用的数据库提供程序)

因此,要解决此问题,您可以尝试将book对象复制到新实例,并将其放入ViewModel集合中,如下所示:

private void GridView_AddBook(Book book)
{
    Book b = new Book
    {
        Title = book.title,
        Author = book.author,
        Publisher = book.publisher,
        ISBN = book.isbn,
        Quantity = book.quantity.GetValueOrDefault(),
        CoverImageLocation = book.CoverImageUri
    };
    ViewModel.Books.Add(b);
}

出现此问题的原因是您从新视图的线程更新了主视图的
ViewModel
。单击
Add
按钮时,会触发
AddBook
事件,这是在新视图的线程上,但会在
YourBooks\u视图
类中更新主视图的
ViewModel
。您应该使用该方法为新视图安排UI线程上的工作

因此,只需使用方法更改
GridView\u AddBook
方法的代码,以调度UI线程上的工作,从而添加新的
Book
对象

以下是
GridView\u AddBook
方法的修改代码:

private async void GridView_AddBook(Book book)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        ViewModel.Books.Add(book);
    });
}

这听起来有点奇怪,但是:你能试着把投掷线用一个任务包起来吗?运行block?我没有得到u@TheTanic。你能说明你的意思吗?把代码行包装起来,这会在一个新任务中抛出错误。运行块,这样在另一个任务中执行。我多次遇到这个错误,这帮我解决了!或者专门使用UI Dispatcher!我还没有使用电脑,所以我无法在第一时间帮你编写代码moment@TheTanic,这就是我所做的:
Task.Run(()=>ViewModel.Books.Add(book))。它给出了以下错误:System.Runtime.InteropServices.COMException HResult=0x8001010E Message=调用接口的应用程序为另一个线程封送。(来自HRESULT的异常:0x8001010E(RPC_E_错误_线程))
我今天尝试了它,您需要调度程序线程。。。我不知道需要哪一个。请您澄清一下您使用的是哪家数据库提供商,好吗?给我们看一些你如何访问数据库的代码?我更新了问题。你还有什么疑问吗?在你的代码中,你已经注释了//不必要的东西,我认为这是你访问数据库的代码,所以重要的是要看到,我只是想确保你正在处理你的dbcontext或包装在一个using语句中?我在问题中添加了一些代码。是的,他们都有一个using语句你的代码看起来很好,在这种情况下似乎出现了一些wierd错误,
private async void GridView_AddBook(Book book)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        ViewModel.Books.Add(book);
    });
}