为ClickOnce部署的WPF应用设置XmlDataProvider的XAML属性
解决WPF ClickOnce部署后找不到XmlDataProvider的XML文件问题
这个坑我踩过!ClickOnce部署时,数据文件不会和exe放在同一个目录,而是被放到用户专属的应用数据文件夹里,所以你原来的相对路径肯定找不到。给你两个实用的解决方案:
方案1:后台代码动态加载XML(最稳妥)
先改XAML,给XmlDataProvider加个名字,去掉硬编码的Source:
<Window.DataContext> <XmlDataProvider x:Name="DbDataProvider" XPath="Databases/Database"/> </Window.DataContext>
然后在窗口的Loaded事件里,根据运行环境切换路径加载文件:
private void Window_Loaded(object sender, RoutedEventArgs e) { string xmlFilePath; // 判断是不是ClickOnce部署环境 if (ApplicationDeployment.IsNetworkDeployed) { // 取ClickOnce的数据目录 string dataDir = ApplicationDeployment.CurrentDeployment.DataDirectory; xmlFilePath = Path.Combine(dataDir, "DbPaths.xml"); } else { // 本地调试时,用exe所在的目录 xmlFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DbPaths.xml"); } // 加载XML到XmlDataProvider var xmlDoc = new XmlDocument(); xmlDoc.Load(xmlFilePath); DbDataProvider.Document = xmlDoc; }
记得给窗口绑定Loaded事件哦,XAML里加Loaded="Window_Loaded"就行。
方案2:用静态属性绑定动态路径(更简洁)
先写个静态类,专门提供路径:
using System; using System.Deployment.Application; using System.IO; namespace 你的应用命名空间 { public static class AppFilePaths { public static string DbXmlPath { get { if (ApplicationDeployment.IsNetworkDeployed) { return Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory, "DbPaths.xml"); } else { return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DbPaths.xml"); } } } } }
然后在XAML里引用这个静态属性,记得先加命名空间:
<Window xmlns:local="clr-namespace:你的应用命名空间" ...> <Window.DataContext> <XmlDataProvider Source="{x:Static local:AppFilePaths.DbXmlPath}" XPath="Databases/Database"/> </Window.DataContext> </Window>
必须做的配置!
别忘给XML文件设置属性:
- 右键项目里的
DbPaths.xml→ 属性 - 生成操作:选「内容」
- 复制到输出目录:选「如果较新则复制」
还有ClickOnce发布时的设置:
- 打开发布向导 → 进入「应用程序文件」页面
- 找到
DbPaths.xml,把「发布状态」改成「数据文件」,这样ClickOnce会自动把它放到数据目录,而且更新应用时会保留用户修改过的内容(如果有需求的话)
内容的提问来源于stack exchange,提问作者Rob Bowman
相关产品推荐
相关产品推荐

