当前位置: 首页 > article >正文

WPF从本地文件加载界面

在前面的文章中,我介绍过一种报告模板的实现思路。就是用的XAML本地加载。

WPF使用XAML实现报表的一种思路(支持外部加载) - zhaotianff - 博客园

在另外一篇文章中,介绍了XAML是如何被转换成对象的。

WPF中的XAML是如何转换成对象的? - zhaotianff - 博客园

在这篇文章中,简单介绍了InitializeComponent函数,它的内部如下:

在任意一个界面的构造函数下都会调用InitializeComponent函数,也就是在InitializeComponent函数里,将XAML加载进来

 1 /// <summary>
 2  /// InitializeComponent
 3  /// </summary>
 4  [System.Diagnostics.DebuggerNonUserCodeAttribute()]
 5  [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
 6  public void InitializeComponent() {
 7      if (_contentLoaded) {
 8          return;
 9      }
10      _contentLoaded = true;
11      System.Uri resourceLocater = new System.Uri("/WpfApp25;component/mainwindow.xaml", System.UriKind.Relative);
12 
13      #line 1 "..\..\MainWindow.xaml"
14      System.Windows.Application.LoadComponent(this, resourceLocater);
15 
16      #line default
17      #line hidden
18  }

如果我们想界面从本地文件加载,是不是也可以利用这种方法呢?

答案是不行,因为Application.LoadComponent函数仅支持相对路径的资源,也就是说必须那是嵌入的。

1  System.Windows.Application.LoadComponent(this, resourceLocater);

但是我们可以利用这种思路,只是改变一下加载方法。

我们还是使用前面的加载报告模板的那种方式。这种方式也支持三方控件。这里以HandyControl为例(HandyControl使用不作讲解)。

如果想为控件添加事件处理程序,可以通过FrameworkElement.FindName函数查找元素,并手动添加事件处理程序。

这里不作演示,本文以MVVM模式进行演示。

实现方式如下:

1、创建一个如下的UserControl

 1 <UserControl x:Class="WPFDynamicLoadUI.UserControl1"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:WPFDynamicLoadUI"
 7              xmlns:hc="https://handyorg.github.io/handycontrol"
 8              mc:Ignorable="d" 
 9              d:DesignHeight="450" d:DesignWidth="800">
10     <hc:TransitioningContentControl>
11         <Grid>
12             <Grid.RowDefinitions>
13                 <RowDefinition/>
14                 <RowDefinition Height="30"/>
15             </Grid.RowDefinitions>
16 
17             <Image></Image>
18             <Button Content="确认" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Width="88" Height="28"></Button>
19         </Grid>
20     </hc:TransitioningContentControl>
21 </UserControl>

2、将UserControl保存到本地文件

在保存之前需要移除一些元素,例如一些资源引入,x:Class声明等,另外还需要将元素进行绑定

 1 <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 2              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 3              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 4              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 5              xmlns:hc="https://handyorg.github.io/handycontrol"
 6              mc:Ignorable="d" 
 7              d:DesignHeight="450" d:DesignWidth="800">
 8     <hc:TransitioningContentControl>
 9         <Grid>
10             <Grid.RowDefinitions>
11                 <RowDefinition/>
12                 <RowDefinition Height="30"/>
13             </Grid.RowDefinitions>
14 
15             <Image Source="{Binding ImagePath}"></Image>
16             <Button Content="确认" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Width="88" Height="28" Command="{Binding ConfirmCommand}"></Button>
17         </Grid>
18     </hc:TransitioningContentControl>
19 </UserControl>

3、创建ViewModel

 1     public class MyViewModel : ObservableObject
 2     {
 3         private string imagePath;
 4 
 5         public string ImagePath 
 6         { 
 7             get => imagePath;
 8             set
 9             {
10                 SetProperty(ref imagePath, value);
11             }
12         }
13 
14         public RelayCommand ConfirmCommand { get; private set; }
15 
16         public MyViewModel()
17         {
18             ConfirmCommand = new RelayCommand(Confirm);
19         }
20 
21         private void Confirm()
22         {
23             Application.Current.MainWindow.Close();
24         }
25     }

4、创建从本地加载的方法

 1    private void LoadUIFromLocalFile()
 2    {
 3        var path = Environment.CurrentDirectory + "\\CustomUI.xaml";
 4 
 5        if (_contentLoaded)
 6        {
 7            return;
 8        }
 9 
10        _contentLoaded = true;
11        System.Uri resourceLocater = new System.Uri(path, System.UriKind.Absolute);
12        System.Windows.Controls.UserControl uc = (System.Windows.Controls.UserControl)XamlReader.Parse(System.IO.File.ReadAllText(path));
13 
14        MyViewModel myViewModel = new MyViewModel();
15        myViewModel.ImagePath = "https://img1.baidu.com/it/u=3587113956,547682065&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1732986000&t=718ac074cdbcbf7e38df3b6ccbd9d8b2";
16        uc.DataContext = myViewModel;
17 
18        this.Content = uc;
19    }

5、移除InitializeConponent函数,变成从本地加载的函数

1    public MainWindow()
2    {
3        //InitializeComponent();
4        LoadUIFromLocalFile();
5    }

运行效果如下:

 示例代码


http://www.kler.cn/a/420854.html

相关文章:

  • 利用红黑树封装map,和set,实现主要功能
  • 【JMX JVM监控】Prometheus读取Trino的JMX数据到Grafana展示
  • Meta-Llama-3-8B-Instruct 模型的混合精度训练显存需求:AdamW优化器(中英双语)
  • 故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab)
  • SpringBoot+MyBatis整合ClickHouse实践
  • 【数据库系列】Liquibase 与 Flyway 的详细对比
  • Modbus rtu转profibusDP接电机保护器快速配置案例
  • 【代码随想录|贪心算法03】
  • 【Trick】adb指令运行时出现 Error: Activity class {xxx} does not exist.
  • 学习笔记048——Java字节流
  • Kotlin 协程的异常处理
  • 蓝象智联携手西电发布GaiaGPT,夯实数据安全底座
  • python(18) : flask_sqlalchemy 配置sqlserver数据库对象
  • 设计模式之 建造者模式 C# 范例
  • 细说STM32单片机用定时器触发DAC输出三角波并通过串口观察波形的方法
  • Microi吾码产品深度测评:轻量级企业管理应用的全方位剖析
  • Python生日祝福烟花
  • 怎么使用开源的 FFmpeg 命令行工具压缩视频大小
  • 【贪心算法】贪心算法五
  • “量子跃迁与数据织网:深入探索K最近邻算法在高维空间中的优化路径、神经网络融合技术及未来机器学习生态系统的构建“
  • java网络通信(三):TCP通信、实现客户端-服务端消息通信
  • 详细介绍下oracle建库过程中核心脚本dbcore.bsq
  • Linux系统编程之进程控制
  • 华为的USG6000为什么不能ping通
  • 微信小程序 运行出错 弹出提示框(获取token失败,请重试 或者 请求失败)
  • 深入探索HarmonyOS next与ArkTS探索