2010-11-02 20 views
11

Stiamo migrando a Winforms alla soluzione basata su WPF. Abbiamo una definizione XML personalizzata che viene utilizzata per compilare il modulo di Windows in fase di runtime.Caricamento XML XAML tramite runtime?

Poiché XAML è basato su XML, possiamo definire un file HelloWorldWindow.xml con definizione XAML e può essere caricato nell'app WPF senza alcun codice dietro i file CSharp? Allegheremo il codice dietro l'hook in fase di runtime.

Come si allega il codice in fase di esecuzione?

+0

Si tratta di un file xml di cui si sta parlando effettivamente una X valida File AML? –

+0

@Steve, sì è un file xaml valido. Ma vogliamo che l'implementazione del codice sia allegata in fase di runtime. –

+0

Hai una soluzione di lavoro di applicare la maggior parte dei concetti MVVM: [La mia soluzione] [1] [1]: http://stackoverflow.com/questions/9021677/loading-xaml-at-runtime-using- the-MVVM-modello-in-WPF/9033544 # 9033544 –

risposta

18

creare un file XML Tempwin.xml utilizzare questo 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> 

Creare un sa mple WPF Applicazione con il codice XAML sotto

<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> 

Incollare il sottostante codice C# in codebehind del Button_Click

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

se si desidera caricare XAML in fase di esecuzione, non si può dare alcun codice dietro il vostro XAML file. Così ho rimosso i x: attributo di classe prima di creare l'xml

Eventi Aggancio ....

<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"); 
    } 
4

È possibile visualizzare in modo dinamico Xaml come questo:

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 

Vedere la classe XamlReader per ulteriori informazioni: http://msdn.microsoft.com/en-us/library/ms613427%28v=VS.95%29.aspx

1

ho fatto caricare XAML in fase di esecuzione, ecco un breve esempio

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>";