如何在 C# WPF 中从 ListView/XML 中完全删除一个项目?

Posted

技术标签:

【中文标题】如何在 C# WPF 中从 ListView/XML 中完全删除一个项目?【英文标题】:How can I completely remove an item out of a ListView/XML in C# WPF? 【发布时间】:2021-03-14 04:07:03 【问题描述】:

应用程序 应用程序本身的目标是管理真正存在的物理键的存在。您可以更改值、添加键(效果很好)并且应该能够删除键(以防错误地添加键等)。 键是 ListView 的项目,当添加/编辑键时,ListView 会保存到 XML 文件中,我正在使用 XmlSerializer 执行此操作。启动应用程序时,它还会将保存的 XML 加载到 ListView 中,这也可以正常工作。

问题 当我尝试直接从 ListView 中删除/删除一个项目(然后再次保存并加载 XMl)时,我的加载方法出现错误,因为 XML 现在具有 多个根元素。当我检查 XML 文件本身时,我可以看到确实键是 从实际的根元素中移出并且 有自己的结束标记,这会导致错误 &使应用程序无法加载。 它看起来像这样:

</ArrayOfSchluessel><Id>12</Id>
    <Schluesselausgefolgt />
    <Raum>0</Raum>
    <ObenUnten />
    <Widmung />
    <Verwahrer />
    <Buntbart xsi:nil="true" />
    <Tosisch xsi:nil="true" />
    <ZahnungZylindrisch xsi:nil="true" />
    <Wende xsi:nil="true" />
    <Doppelbart xsi:nil="true" />
    <Andere xsi:nil="true" />
    <Gesamtbestand>0</Gesamtbestand>
    <Alarmschluessel>0</Alarmschluessel>
    <Reserveschluesselkasten>0</Reserveschluesselkasten>
    <HakenNummer>0</HakenNummer>
    <Seite>0</Seite>
    <Ausgabegrund>0</Ausgabegrund>
  </Schluessel>
</ArrayOfSchluessel>

(其中 ID 为 12 的密钥是被删除的密钥)。我的删除方法如下:

public void SchluesselLoeschen(Schluessel ZuLoeschenderSchluessel)
        

            SchluesselListeItemSource.Remove(ZuLoeschenderSchluessel);
            SchluesselListe.ItemsSource = SchluesselListeItemSource;
            

            SchluesselSpeichernXML();
            SchluesselLadenXML();

            MessageBox.Show("Schlüssel erfolgreich gelöscht!", "Erfolg");
        

除了 .Remove() 而不是 .Add() 之外,它看起来与工作中的 Add 方法几乎相同。正如你所看到的,我正在使用一种解决方法,因为我正在使用 ItemSource(加载/保存),它可以很好地添加并且在这种删除的情况下让我感到困惑。 SchluesselListeItemSource 对象是一个 List 并作为 ListView 的实际 ItemSource SchluesselListe临时占位符/保存程序 . ZuLoeschenderSchluessel 对象是从另一个窗口(编辑窗口)解析的 ListView 的选定键。我的保存方法如下:

public void SchluesselSpeichernXML()
        

            XmlSerializer serializer = new XmlSerializer(typeof(List<Schluessel>));

            using (FileStream stream = File.OpenWrite(DateiPfadHC))
            
                serializer.Serialize(stream, SchluesselListe.ItemsSource);
            
        

和加载方法:

public void SchluesselLoeschen(Schluessel ZuLoeschenderSchluessel)
        

            SchluesselListeItemSource.Remove(ZuLoeschenderSchluessel);
            SchluesselListe.ItemsSource = SchluesselListeItemSource;
            

            SchluesselSpeichernXML();
            SchluesselLadenXML();

            MessageBox.Show("Schlüssel erfolgreich gelöscht!", "Erfolg");
        

Schluessel 对象本身(即/是 List/ListView 内的对象)是我的键模型。它只包含一个键应该能够保存的所有不同值(使用 getter 和 setter)和一个公共构造函数(它只创建一个带有 id 的键),我用它来添加新的键(在之后编辑)。

我尝试使用几种不同类型的列表或保存对象,但由于它在某种程度上删除了项目,只是不完全,并且添加方法正在工作我想不出解决方案并且无法找到相关内容网络,这确实与此相似,因为我的工作非常接近 XML 文件,这是这个应用程序的一个重要因素。

【问题讨论】:

您是否尝试删除旧文件。或者尝试覆盖旧文件? @Ugur 删除整个文件并没有真正改变任何东西。在我添加新密钥并尝试删除相同的事情之后。我不知道 XmlSerializer 究竟是如何工作的,但我相信它已经覆盖了文件。我错了吗? 可能还有其他问题。您需要分享您的关键课程“Schluessel”。以及如何在删除方法中获得“ZuLoeschenderSchluessel”。 而且您可能需要将根类更改为像容器类一样保存密钥等。 @Ugur 请稍等,我会添加代码和解释 【参考方案1】:

看起来您将数据写入现有文件,然后是新旧数据的混合。

所以将File.OpenWrite(DateiPfadHC)) 替换为new FileStream(DateiPfadHC, FileMode.Create, FileAccess.Write, FileShare.None)

因为File.OpenWrite 确实使用FileMode.OpenOrCreate 创建了一个流。

FileMode.Create:

指定操作系统应该创建一个新文件。 如果 文件已经存在,它将被覆盖。这需要写 允许。 FileMode.Create 相当于请求如果 文件不存在,使用 CreateNew;否则,使用截断。如果 文件已经存在但是是一个隐藏文件,一个 抛出 UnauthorizedAccessException 异常。

FileMode.OpenOrCreate:

指定操作系统应该打开一个文件(如果存在); 否则,应创建一个新文件。如果文件是用 FileAccess.Read,需要读取权限。如果文件访问是 FileAccess.Write,需要写权限。如果文件被打开 使用 FileAccess.ReadWrite,读取和写入权限都是 必填。

【讨论】:

不客气!顺便说一句,主和救主是JC。 ;) Ofc,我只是用它作为一个短语,因为我觉得它合适;-)

以上是关于如何在 C# WPF 中从 ListView/XML 中完全删除一个项目?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# WPF 中从 MySQL 数据库中填充 dataGrid

在 C# Webbrowser 控件 WPF 中从 Javascript 获取返回值

C# WPF后台动态添加控件(经典)

C# WPF后台动态添加控件(经典)

WebView2:在 C# 中从 Javascript 代码设置对象属性

如何在 WPF 中从一个窗口移动到另一个窗口?