Загрузка XAML XML во время выполнения? - PullRequest
12 голосов
/ 02 ноября 2010

Мы переходим на решение Winforms для WPF. У нас есть пользовательское определение XML, которое используется для построения формы Windows во время выполнения.

Поскольку XAML основан на XML, можем ли мы определить файл HelloWorldWindow.xml с определением XAML и можно ли его загрузить в приложение WPF без какого-либо кода в файлах CSharp? Мы прикрепим код за крючком во время выполнения.

Как прикрепить код позади во время выполнения?

Ответы [ 3 ]

19 голосов
/ 02 ноября 2010

Создайте XML-файл Tempwin.xml, используя этот XAML

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" Background="Transparent" >
<Border Background="Black" CornerRadius="10" BorderThickness="4" BorderBrush="RoyalBlue">
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="Sample Text" Foreground="White" Margin="2"></TextBlock>
        <TextBox Grid.Row="1" Margin="5"> </TextBox>
        <TextBlock Text="Sample Text 1" Grid.Row="2" Foreground="White" Margin="2"></TextBlock>
        <TextBox Grid.Row="3" Margin="5"></TextBox>
        <Ellipse Fill="Red" Height="100" Width="100" Grid.Row="4" Margin="0,10,0,0"></Ellipse>
    </Grid>
    </Border>

Создайте образец приложения WPF со следующим xaml

<Window x:Class="WpfApplication12.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="600">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>

    </Grid.RowDefinitions>

    <Button Height="25" Width="100" Margin="2" Click="Button_Click"> Show Content</Button>
    <Grid x:Name="content" Grid.Row="1" Margin="2">

    </Grid>
</Grid>

Вставьте приведенный ниже код C # в код позади Button_Click

  StreamReader mysr = new StreamReader(@"D:\Tempwin.xml");
        FrameworkElement  rootObject = XamlReader.Load(mysr.BaseStream) as FrameworkElement;
        content.Children.Add(rootObject);

. Если вы хотите загрузить xaml во время выполнения, вы не можете дать какой-либо код за вашим XAML-файлом.Поэтому я удалил атрибут x: Class перед созданием xml

Перехват событий ....

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" Background="Transparent" >
<Border Background="Black" CornerRadius="10" BorderThickness="4" BorderBrush="RoyalBlue">
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="Sample Text" Foreground="White" Margin="2"></TextBlock>
        <TextBox Grid.Row="1" Margin="5"> </TextBox>
        <TextBlock Text="Sample Text 1" Grid.Row="2" Foreground="White" Margin="2"></TextBlock>
        <TextBox Grid.Row="3" Margin="5"></TextBox>
        <Ellipse Fill="Red" Height="100" Width="100" Grid.Row="4" Margin="0,10,0,0"></Ellipse>
        <Button Grid.Row="5" Height="25" Content="Event added at Runtime" x:Name="btnTest"></Button>
    </Grid>
    </Border>

Button ButtoninXAML;

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        StreamReader mysr = new StreamReader(@"D:\Tempwin.xml");
        FrameworkElement  rootObject = XamlReader.Load(mysr.BaseStream) as FrameworkElement;
        ButtoninXAML = LogicalTreeHelper.FindLogicalNode(rootObject, "btnTest") as Button;
        ButtoninXAML.Click += new RoutedEventHandler(Button_Click1); 

        content.Children.Add(rootObject);

    }
    private void Button_Click1(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Added At Runtime");
    }
5 голосов
/ 02 ноября 2010

Вы можете динамически отображать Xaml следующим образом:

    string text = @"<TextBlock Text='test' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' />";

    // Convert to stream
    // You can also just stream the xaml from a file, using a FileStream
    MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(text));

    // Convert to object
    TextBlock block = (TextBlock)System.Windows.Markup.XamlReader.Load(stream);

    //... now you can put that TextBlock somewhere, for example in your main Window

См. Класс XamlReader для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/ms613427%28v=VS.95%29.aspx

2 голосов
/ 30 мая 2013

Я выполнил загрузку XAML во время выполнения, вот краткий пример

Grid grd = new Grid();
var grdEncoding = new ASCIIEncoding();
var grdBytes = grdEncoding.GetBytes(myXAML);
grd = (Grid)XamlReader.Load(new MemoryStream(grdBytes));
Grid.SetColumn(grd, 0);
Grid.SetRow(grd, 0);
parentGrid.Children.Add(grd);

private String myXAML = @" <Grid xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' Margin='30 10 30 65' VerticalAlignment='Bottom'>" +
                "<Label Content='Date: 1-Feb-2013' FontFamily='Arial' FontSize='12' Foreground='#666666' HorizontalAlignment='Left'/>" +
                "<Label Content='4'  FontFamily='Arial' FontSize='12' Foreground='#666666' HorizontalAlignment='Center'/>" +
                "<Label Content='Hello World'  FontFamily='Arial' FontSize='12' Foreground='#666666' HorizontalAlignment='Right'/>" +
            "</Grid>";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...