C# 在程序运行时编译/执行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=

我想创建一个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="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();
            }
        }