2010-11-02 14 views
11

Przeprowadzamy migrację do WinForm na rozwiązanie oparte na WPF. Mamy niestandardową definicję XML, która służy do budowania postaci okna w czasie wykonywania.Ładowanie XML XAML przez środowisko wykonawcze?

Ponieważ XAML jest oparty na XML, czy możemy zdefiniować plik HelloWorldWindow.xml z definicją XAML i czy można go załadować do aplikacji WPF bez żadnego kodu za plikami CSharp? Kod zostanie załączony za hakiem w czasie wykonywania.

Jak dołączyć kod w czasie wykonywania?

+0

Czy ten plik xml mówi o prawdziwym X Plik AML? –

+0

@Steve, tak, jest to prawidłowy plik xaml. Ale chcemy, aby implementacja kodu była dołączana w czasie wykonywania. –

+0

Mam roztwór roboczy stosowania większości pojęć MVVM: [Moje rozwiązanie] [1] [1]: http://stackoverflow.com/questions/9021677/loading-xaml-at-runtime-using- wzorzec-mvvm-wp-wpf/9033544 # 9033544 –

Odpowiedz

18

Utwórz plik XML Tempwin.xml użyciu tego 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> 

Utwórz sa Zastosowanie MPle WPF z poniższym 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> 

Wklej poniższy kod C# w kodzie z Button_Click

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

jeśli chcesz załadować XAML w czasie wykonywania nie można podać żadnego kodu za swoim XAML plik. Więc mam usunięte x: Przed utworzeniem klasy atrybutu xml

Wydarzenia zaczepiając ....

<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

można wyświetlać XAML dynamicznie tak:

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 

Zobacz klasę XamlReader celu uzyskania dalszych informacji: http://msdn.microsoft.com/en-us/library/ms613427%28v=VS.95%29.aspx

1

Zrobiłem ładuje XAML w czasie wykonywania, jest tutaj krótki przykład:

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>"; 
Powiązane problemy