C# 在程序运行时编译/执行XAML
我想创建一个WPF应用程序,它从数据库中检索XAML代码并显示检索到的代码 假设数据库返回以下代码:C# 在程序运行时编译/执行XAML,c#,wpf,xaml,runtime,code-generation,C#,Wpf,Xaml,Runtime,Code Generation,我想创建一个WPF应用程序,它从数据库中检索XAML代码并显示检索到的代码 假设数据库返回以下代码: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title=
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="mainGrid">
<Button Content="test case 1"
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"
Width="100"
Click="TestCase1_OnClick"
Height="29"/>
</Grid>
</Window>
如何在运行时执行此代码(或者可能只是主网格的内容) 课程就是为了这个目的而设计的。使用其方法动态加载xaml
编辑-此链接可能会引起您的兴趣。我就是这样解决问题的: 我有3个文件MainWindow.xaml、MainWindow.xaml.cs和wpftest.csproj MainWindow.xaml:
<Window x:Class="wpftest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="122,75,0,0" VerticalAlignment="Top" Width="75" Click="ButtonBase_OnClick"/>
</Grid>
</Window>
MainWindow.xaml.cs
namespace wpftest
{
using System.Windows;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello world", "does it work?");
}
}
}
名称空间wpftest
{
使用System.Windows;
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
private void按钮base_OnClick(对象发送方,RoutedEventTarget e)
{
显示(“你好,世界”,“它能用吗?”);
}
}
}
wpftest.csproj
(注意:此文件非常大,大部分内容都不是必需的。您可以按照以下指南创建更简化的解决方案:)
调试
任意CPU
{E3FBAE41-AF7E-4C7E-A69E-ADEAEE76FA2}
图书馆
为此
private void TestCase4\u OnClick(对象发送方,RoutedEventArgs e)
{
var globalProperties=新字典();
var buildRequest=newbuildrequestdata(@“C:\Users\jbu\wpftest\wpftest.csproj”,globalProperties,null,新字符串[]{“Build”},null);
var pc=新项目集合();
var result=BuildManager.DefaultBuildManager.Build(新的BuildParameters(pc)、buildRequest);
Assembly Assembly=Assembly.LoadFrom(@“C:\Users\jbu\wpftest\bin\Debug\wpftest.dll”);
var instance=assembly.CreateInstance(“wpftest.MainWindow”)作为窗口;
if(实例!=null)
{
Show();
}
}
这是一个老问题,但我想建议一种更好的方法,无需在运行时编译
将“单击”属性替换为“命令”。执行中继命令或其他第三方库(例如:
) . 也会有帮助
从窗口节点的xaml中删除x:Class
属性
现在,您有了一个松散的xaml,任务可以由XamlReader完成。据我所知,XamlReader将不适用于事件处理程序(Click=“TestCase1_OnClick”)是的,您无法使用它创建处理程序,因为它不再是松散的xaml
。只能加载松散的XAML。为什么要从数据库加载XAML。如果您解释了您试图实现的目标,可能会建议一种替代实现。例如,我宁愿在内部构建模板,然后从DB获取参数,而不是将Xaml存储在DB中。@Joel-我认为您应该重新设计代码。但是,如果您想坚持使用它,可以使用CodeDom
动态创建处理程序。这里的链接可能是您感兴趣的。没有数据库,我只是创建了一个案例来指出问题。真正的问题要复杂得多。但是,让我们来试一试,这就是我试图实现的:我从一个Web服务接收一个XML文件中定义的用户界面和一个相应的c#代码隐藏文件。必须将XML文件解析为XAML。然后我必须以某种方式显示生成的XAML文件。基本上,我必须在运行时用xml文件创建一个用户界面。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E3FBAE41-AF7E-4C7E-A69E-ADAEAEE76FA2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>wpftest</RootNamespace>
<AssemblyName>wpftest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
private void TestCase4_OnClick(object sender, RoutedEventArgs e)
{
var globalProperties = new Dictionary<string, string>();
var buildRequest = new BuildRequestData(@"C:\Users\jbu\wpftest\wpftest.csproj", globalProperties, null, new string[] { "Build" }, null);
var pc = new ProjectCollection();
var result = BuildManager.DefaultBuildManager.Build(new BuildParameters(pc), buildRequest);
Assembly assembly = Assembly.LoadFrom(@"C:\Users\jbu\wpftest\bin\Debug\wpftest.dll");
var instance = assembly.CreateInstance("wpftest.MainWindow") as Window;
if (instance != null)
{
instance.Show();
}
}