2016-04-29 1 views
0

Ich habe eine Lösung mit einer WPF-Steuerbibliothek - mit einigen UserControls - und einer WPF-Anwendung, die die UserControls aus der Bibliothek verwenden soll. Ich habe die Bibliothek als Projektverweis hinzugefügt. In der WPF-Anwendung habe ich zwei WPF-Windows. Eins mit den Steuerelementen (wie eine TooBox) und ein anderes, zu dem ich die Steuerelemente per Drag-and-Drop übertragen/kopieren möchte. Wenn ich eines meiner UserControls im zweiten Fenster lösche, erhalte ich eine Zeichenkette mit dem xaml von einem gezogenen Element durch Verwendung von XamlDesignerSerializationManager. Dann versuche ich ein FrameworkElement aus dem XAML-String mit StringReader und XmlReader zu erstellen. An diesem Punkt erhalte ich eine System.Windows.Markup.XamlParseException, weil der Name "Grenze" - die ich in der UserControl XAML verwendet - zweimal vorhanden ist und nicht registriert werden kann.Namen von Subcontrols in WPF UserControl können nicht nach Drag & Drop registriert werden

Kann jemand erklären, warum das passiert?

Hier ist die XAML für eine der Benutzersteuerelemente:

<UserControl x:Class="WpfDesignerControlLibrary.ControlLabel" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfDesignerControlLibrary" 
      mc:Ignorable="d" 
      d:DesignHeight="30" 
      d:DesignWidth="150"> 
    <UserControl.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Resources.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </UserControl.Resources> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <Border Name="border" 
       Style="{StaticResource usercontrolBorderStyle}"> 
      <Label Name="label" 
        Margin="2"> 
       <TextBlock Name="textblock" 
          Text="Label" 
          TextWrapping="Wrap"/> 
      </Label> 
     </Border> 
    </Grid> 
</UserControl> 

Was ich aus dem XamlDesignerSerializationManager erhalten, wenn die gezogene Kontrolle Serialisierung:

<ControlLabel Text="Label" ControlHorizontalContentAlignment="Left" ControlVerticalContentAlignment="Top" FontIsBold="True" FontStyleIsItalic="False" TextIsUnderlined="False" FontWeight="Bold" Name="label21" av:Canvas.Left="103" av:Canvas.Top="214" xmlns="clr-namespace:WpfDesignerControlLibrary;assembly=WpfDesignerControlLibrary" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <ControlLabel.TextDecorations> 
    <av:TextDecorationCollection /> 
    </ControlLabel.TextDecorations> 
    <av:Grid> 
    <av:Grid.ColumnDefinitions> 
     <av:ColumnDefinition /> 
    </av:Grid.ColumnDefinitions> 
    <av:Grid.RowDefinitions> 
     <av:RowDefinition Height="*" /> 
    </av:Grid.RowDefinitions> 
    <av:Border Name="border"> 
     <av:Border.Style> 
     <av:Style TargetType="av:IFrameworkInputElement"> 
      <av:Style.Resources> 
      <av:ResourceDictionary /> 
      </av:Style.Resources> 
      <av:Setter Property="av:Border.BorderBrush"> 
      <av:Setter.Value> 
       <av:SolidColorBrush>#FF4169E1</av:SolidColorBrush> 
      </av:Setter.Value> 
      </av:Setter> 
      <av:Setter Property="av:Border.BorderThickness"> 
      <av:Setter.Value> 
       <av:Thickness>1,1,1,1</av:Thickness> 
      </av:Setter.Value> 
      </av:Setter> 
      <av:Setter Property="av:FrameworkElement.HorizontalAlignment"> 
      <av:Setter.Value> 
       <x:Static Member="av:HorizontalAlignment.Stretch" /> 
      </av:Setter.Value> 
      </av:Setter> 
      <av:Setter Property="av:FrameworkElement.VerticalAlignment"> 
      <av:Setter.Value> 
       <x:Static Member="av:VerticalAlignment.Stretch" /> 
      </av:Setter.Value> 
      </av:Setter> 
     </av:Style> 
     </av:Border.Style> 
     <av:Label Name="label" Margin="2,2,2,2"> 
     <av:TextBlock Text="Label" TextWrapping="Wrap" Name="textblock" /> 
     </av:Label> 
    </av:Border> 
    </av:Grid> 
</ControlLabel> 

Dies ist die Methode, mit der ich die XAML bekommen als String aus dem gezogenen Steuerelement:

public string SerializeControlToXaml(FrameworkElement control) 
{ 
    StringBuilder outstr = new StringBuilder(); 

    //this code need for right XML fomating 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true; 
    settings.OmitXmlDeclaration = true; 
    XamlDesignerSerializationManager dsm = 
     new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings)); 
    //this string need for turning on expression saving mode 
    dsm.XamlWriterMode = XamlWriterMode.Expression; 
    System.Windows.Markup.XamlWriter.Save(control, dsm); 

    string xaml = outstr.ToString(); 
    return xaml; 
} 

Und zuletzt die Methode whi ch erzeugt den Fehler (in der letzten Zeile des Codes):

public object DeserializeXaml(string xaml) 
{ 
    StringReader stringReader = new StringReader(xaml); 
    XmlReader xmlReader = XmlReader.Create(stringReader); 
    return System.Windows.Markup.XamlReader.Load(xmlReader); 
} 

Antwort

0

Ich habe es herausgefunden. Sie müssen alle Namen aus der UserControl-Definition entfernen und ein ViewModel verwenden.